问题:2个列表之间的共同元素比较

def common_elements(list1, list2):
    """
    Return a list containing the elements which are in both list1 and list2

    >>> common_elements([1,2,3,4,5,6], [3,5,7,9])
    [3, 5]
    >>> common_elements(['this','this','n','that'],['this','not','that','that'])
    ['this', 'that']
    """
    for element in list1:
        if element in list2:
            return list(element)

到现在为止,但是似乎无法正常工作!

有任何想法吗?

def common_elements(list1, list2):
    """
    Return a list containing the elements which are in both list1 and list2

    >>> common_elements([1,2,3,4,5,6], [3,5,7,9])
    [3, 5]
    >>> common_elements(['this','this','n','that'],['this','not','that','that'])
    ['this', 'that']
    """
    for element in list1:
        if element in list2:
            return list(element)

Got that so far, but can’t seem to get it to work!

Any ideas?


回答 0

>>> list1 = [1,2,3,4,5,6]
>>> list2 = [3, 5, 7, 9]
>>> list(set(list1).intersection(list2))
[3, 5]
>>> list1 = [1,2,3,4,5,6]
>>> list2 = [3, 5, 7, 9]
>>> list(set(list1).intersection(list2))
[3, 5]

回答 1

您还可以使用集合并在一行中获得共性:从其中一个集合中减去包含差异的集合。

A = [1,2,3,4]
B = [2,4,7,8]
commonalities = set(A) - (set(A) - set(B))

You can also use sets and get the commonalities in one line: subtract the set containing the differences from one of the sets.

A = [1,2,3,4]
B = [2,4,7,8]
commonalities = set(A) - (set(A) - set(B))

回答 2

所建议的解决方案S.MarkSilentGhost通常告诉你应该如何在一个Python化的方式来完成,但我认为从知道为什么你的解决方案不工作,你也可能受益。问题在于,一旦您在两个列表中找到第一个公共元素,就只返回该单个元素。您可以通过创建一个result列表并收集该列表中的常见元素来解决您的问题:

def common_elements(list1, list2):
    result = []
    for element in list1:
        if element in list2:
            result.append(element)
    return result

使用列表推导的更短版本:

def common_elements(list1, list2):
    return [element for element in list1 if element in list2]

但是,正如我说的那样,这是一种非常低效的方式-Python的内置集合类型在内部用C实现时效率更高。

The solutions suggested by S.Mark and SilentGhost generally tell you how it should be done in a Pythonic way, but I thought you might also benefit from knowing why your solution doesn’t work. The problem is that as soon as you find the first common element in the two lists, you return that single element only. Your solution could be fixed by creating a result list and collecting the common elements in that list:

def common_elements(list1, list2):
    result = []
    for element in list1:
        if element in list2:
            result.append(element)
    return result

An even shorter version using list comprehensions:

def common_elements(list1, list2):
    return [element for element in list1 if element in list2]

However, as I said, this is a very inefficient way of doing this — Python’s built-in set types are way more efficient as they are implemented in C internally.


回答 3

使用集合相交,集合(list1)和集合(list2)

>>> def common_elements(list1, list2):
...     return list(set(list1) & set(list2))
...
>>>
>>> common_elements([1,2,3,4,5,6], [3,5,7,9])
[3, 5]
>>>
>>> common_elements(['this','this','n','that'],['this','not','that','that'])
['this', 'that']
>>>
>>>

请注意,结果列表可能与原始列表的顺序不同。

use set intersections, set(list1) & set(list2)

>>> def common_elements(list1, list2):
...     return list(set(list1) & set(list2))
...
>>>
>>> common_elements([1,2,3,4,5,6], [3,5,7,9])
[3, 5]
>>>
>>> common_elements(['this','this','n','that'],['this','not','that','that'])
['this', 'that']
>>>
>>>

Note that result list could be different order with original list.


回答 4

您可以使用简单的列表理解:

x=[1,2,3,4]
y=[3,4,5]
common = [i for i in x if i in y]
common: [3,4]

you can use a simple list comprehension:

x=[1,2,3,4]
y=[3,4,5]
common = [i for i in x if i in y]
common: [3,4]

回答 5

设置是我们可以解决此问题的另一种方法

a = [3,2,4]
b = [2,3,5]
set(a)&set(b)
{2, 3}

Set is another way we can solve this

a = [3,2,4]
b = [2,3,5]
set(a)&set(b)
{2, 3}

回答 6

list1 = [1,2,3,4,5,6] list2 = [3,5,7,9]

我知道3种方法可以解决此问题,当然可能还有更多方法。

1-

common_elements = [e for e in list1 if e in list2]

2

import numpy as np
common_elements = np.intersect1d(list1, list2)

3

common_elements = set(list1).intersection(list2)

第三种方法最快,因为使用哈希表实现了集。

list1 = [1,2,3,4,5,6]
list2 = [3,5,7,9]

I know 3 ways can solve this, Of course, there could be more.

1-

common_elements = [e for e in list1 if e in list2]

2-

import numpy as np
common_elements = np.intersect1d(list1, list2)

3-

common_elements = set(list1).intersection(list2)

The 3rd way is the fastest because Sets are implemented using hash tables.


回答 7

前面的答案都可以找到唯一的共同要素,但是无法解释列表中的重复项。如果希望公用元素以与列表中常见的元素相同的数字出现,则可以使用以下一线:

l2, common = l2[:], [ e for e in l1 if e in l2 and (l2.pop(l2.index(e)) or True)]

or True仅当您希望对任何元素求值时,才需要该零件False

The previous answers all work to find the unique common elements, but will fail to account for repeated items in the lists. If you want the common elements to appear in the same number as they are found in common on the lists, you can use the following one-liner:

l2, common = l2[:], [ e for e in l1 if e in l2 and (l2.pop(l2.index(e)) or True)]

The or True part is only necessary if you expect any elements to evaluate to False.


回答 8

我比较了每个答案提到的每种方法。目前,我将python 3.6.3用于此实现。这是我使用的代码:

import time
import random
from decimal import Decimal


def method1():
    common_elements = [x for x in li1_temp if x in li2_temp]
     print(len(common_elements))


def method2():
    common_elements = (x for x in li1_temp if x in li2_temp)
    print(len(list(common_elements)))


def method3():
    common_elements = set(li1_temp) & set(li2_temp)
    print(len(common_elements))


def method4():
    common_elements = set(li1_temp).intersection(li2_temp)
    print(len(common_elements))


if __name__ == "__main__":
    li1 = []
    li2 = []
    for i in range(100000):
        li1.append(random.randint(0, 10000))
        li2.append(random.randint(0, 10000))

    li1_temp = list(set(li1))
    li2_temp = list(set(li2))

    methods = [method1, method2, method3, method4]
    for m in methods:
        start = time.perf_counter()
        m()
        end = time.perf_counter()
        print(Decimal((end - start)))

如果运行此代码,则可以看到如果使用列表或生成器(如果迭代生成器,而不仅仅是使用它。我在强制生成器打印其长度时执行了此操作),则可获得几乎相同的性能。但是,如果使用set,则可以获得更好的性能。同样,如果您使用交集方法,您将获得更好的性能。下面列出了我计算机中每种方法的结果:

  1. 方法1:0.8150673999999999974619413478649221360683441
  2. 方法2:0.8329545000000001531148541289439890533685684
  3. 方法3:0.0016547000000000089414697868051007390022277
  4. 方法4:0.0010262999999999244948867271887138485908508

I compared each of method that each answer mentioned. At this moment I use python 3.6.3 for this implementation. This is the code that I have used:

import time
import random
from decimal import Decimal


def method1():
    common_elements = [x for x in li1_temp if x in li2_temp]
     print(len(common_elements))


def method2():
    common_elements = (x for x in li1_temp if x in li2_temp)
    print(len(list(common_elements)))


def method3():
    common_elements = set(li1_temp) & set(li2_temp)
    print(len(common_elements))


def method4():
    common_elements = set(li1_temp).intersection(li2_temp)
    print(len(common_elements))


if __name__ == "__main__":
    li1 = []
    li2 = []
    for i in range(100000):
        li1.append(random.randint(0, 10000))
        li2.append(random.randint(0, 10000))

    li1_temp = list(set(li1))
    li2_temp = list(set(li2))

    methods = [method1, method2, method3, method4]
    for m in methods:
        start = time.perf_counter()
        m()
        end = time.perf_counter()
        print(Decimal((end - start)))

If you run this code you can see that if you use list or generator(if you iterate over generator, not just use it. I did this when I forced generator to print length of it), you get nearly same performance. But if you use set you get much better performance. Also if you use intersection method you will get a little bit better performance. the result of each method in my computer is listed bellow:

  1. method1: 0.8150673999999999974619413478649221360683441
  2. method2: 0.8329545000000001531148541289439890533685684
  3. method3: 0.0016547000000000089414697868051007390022277
  4. method4: 0.0010262999999999244948867271887138485908508

回答 9

这是我的命题, 我认为使用set比使用for循环更容易

def unique_common_items(list1, list2):
   # Produce the set of *unique* common items in two lists.
   return list(set(list1) & set(list2))

this is my proposition i think its easier with sets than with a for loop

def unique_common_items(list1, list2):
   # Produce the set of *unique* common items in two lists.
   return list(set(list1) & set(list2))

回答 10

为什么不使用list comprehension

半线解决方案:

common_elements = [x for x in list1 if x in list2]

Just use list comprehension.

Half line solution:

common_elements = [x for x in list1 if x in list2]

If that helped, consider upvoting my answer.


回答 11

1)方法1将list1保存为字典,然后迭代list2中的每个elem

def findarrayhash(a,b):
    h1={k:1 for k in a}
    for val in b:
        if val in h1:
            print("common found",val)
            del h1[val]
        else:
            print("different found",val)
    for key in h1.iterkeys():
        print ("different found",key)

查找常见和不同元素:

2)方法2使用设置

def findarrayset(a,b):
    common = set(a)&set(b)
    diff=set(a)^set(b)
    print list(common)
    print list(diff) 

1) Method1 saving list1 is dictionary and then iterating each elem in list2

def findarrayhash(a,b):
    h1={k:1 for k in a}
    for val in b:
        if val in h1:
            print("common found",val)
            del h1[val]
        else:
            print("different found",val)
    for key in h1.iterkeys():
        print ("different found",key)

Finding Common and Different elements:

2) Method2 using set

def findarrayset(a,b):
    common = set(a)&set(b)
    diff=set(a)^set(b)
    print list(common)
    print list(diff) 

回答 12

使用生成器:

common = (x for x in list1 if x in list2)

这样做的好处是,即使使用巨大的列表或其他巨大的可迭代对象,它也将在恒定时间(几乎即时)中返回。

例如,

list1 =  list(range(0,10000000))
list2=list(range(1000,20000000))
common = (x for x in list1 if x in list2)

使用list1和list2的这些值,此处所有其他答案将花费很长时间。

然后,您可以使用来迭代答案

for i in common: print(i)

或将其转换为列表

list(i)

Use a generator:

common = (x for x in list1 if x in list2)

The advantage here is that this will return in constant time (nearly instant) even when using huge lists or other huge iterables.

For example,

list1 =  list(range(0,10000000))
list2=list(range(1000,20000000))
common = (x for x in list1 if x in list2)

All other answers here will take a very long time with these values for list1 and list2.

You can then iterate the answer with

for i in common: print(i)

Or convert it to a list with

list(i)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。