2个列表之间的常见元素比较

时间:2010-05-19 10:57:02

标签: python list

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)

到目前为止,但似乎无法让它工作!

有什么想法吗?

21 个答案:

答案 0 :(得分:185)

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

答案 1 :(得分:38)

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

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

答案 2 :(得分:31)

S.MarkSilentGhost建议的解决方案通常会告诉您应该如何以Pythonic方式完成,但我认为您也可以从了解为什么您的解决方案不起作用中受益。问题是,只要找到两个列表中的第一个公共元素,就只返回该单个元素。您可以通过创建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内部实现。

答案 3 :(得分:24)

使用set intersectionctions,set(list1)&集(列表2)

>>> 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']
>>>
>>>

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

答案 4 :(得分:18)

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)

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

答案 5 :(得分:10)

之前的答案都是为了找到唯一的共同元素,但无法解释列表中重复的项目。如果您希望公共元素显示在列表中常见的相同数字上,您可以使用以下单行:

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

只有在您希望任何元素评估为or True时才需要False部分。

答案 6 :(得分:9)

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

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

答案 7 :(得分:4)

这是我的主张 我认为使用set比使用for循环更容易

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

答案 8 :(得分:2)

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 使用set

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

答案 9 :(得分:2)

使用生成器:

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)

答案 10 :(得分:2)

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

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

答案 11 :(得分:1)

嗨,这是我的建议(非常简单)

import random

i = [1,4,10,22,44,6,12] #first random list, could be change in the future
j = [1,4,10,8,15,14] #second random list, could be change in the future
for x in i: 
    if x in j: #for any item 'x' from collection 'i', find the same item in collection of 'j'
        print(x) # print out the results

答案 12 :(得分:1)

我比较了每个答案提到的每种方法。目前,我将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.0016547000000000089414697868051007307390022277
  4. 方法4:0.0010262999999999244244948867271887138485908508

答案 13 :(得分:1)

您的问题是您要从for循环内部返回,因此只会得到第一个匹配项。解决方案是将退货单移出循环。

def elementosEnComunEntre(lista1,lista2):

    elementosEnComun = set()

    for e1 in lista1:
         if(e1 in lista2):
             elementosEnComun.add(e1)

    return list(elementosEnComun)

答案 14 :(得分:1)

list_1=range(0,100)
list_2=range(0,100,5)
final_list=[]
for i in list_1:
    for j in list_2:
        if i==j:
            final_list.append(i)
print(set(final_list))

答案 15 :(得分:1)

def common_member(a, b): 
    a_set = set(a) 
    b_set = set(b) 
    if (a_set & b_set): 
        print(a_set & b_set) 
    else: 
        print("No common elements") 

答案 16 :(得分:1)

f_list=[1,2,3,4,5] # First list
s_list=[3,4,5,6,7,8] # Second list
# An empty list stores the common elements present in both the list
common_elements=[]

for i in f_list:
    # checking if each element of first list exists in second list
    if i in s_list:
        #if so add it in common elements list
        common_elements.append(i) 
print(common_elements)

答案 17 :(得分:1)

a_list = range(1,10)
b_list = range(5, 25)
both = []

for i in b_list:
    for j in a_list:
        if i == j:
            both.append(i)

答案 18 :(得分:1)

这是我提出的一种相当蛮力的方法。它当然不是效率最高的,而是它的一部分。

我在这里找到的一些解决方案的问题是,它既没有给出重复的元素,也没有在输入顺序重要时给出正确数量的元素。

#finds common elements
def common(list1, list2):
    result = []
    intersect = list(set(list1).intersection(list2))

    #using the intersection, find the min
    count1 = 0
    count2 = 0
    for i in intersect: 
        for j in list1:
            if i == j:
                count1 += 1
        for k in list2: 
            if i == k:
                count2 += 1
        minCount = min(count2,count1)
        count1 = 0
        count2 = 0

        #append common factor that many times
        for j in range(minCount):
            result.append(i)

    return result

答案 19 :(得分:0)

这里有一些解决方案在 O(l1+l2) 中不计算重复项,而慢速解决方案(至少 O(l1*l2),但可能更昂贵)确实考虑了重复项。< /p>

所以我想我应该添加一个 O(l1log(l1)+l2(log(l2)) 解决方案。如果列表已经排序,这特别有用。

def common_elems_with_repeats(first_list, second_list):
    first_list = sorted(first_list)
    second_list = sorted(second_list)
    marker_first = 0
    marker_second = 0
    common = []
    while marker_first < len(first_list) and marker_second < len(second_list):
        if(first_list[marker_first] == second_list[marker_second]):
            common.append(first_list[marker_first])
            marker_first +=1
            marker_second +=1
        elif first_list[marker_first] > second_list[marker_second]:
            marker_second += 1
        else:
            marker_first += 1
    return common

另一种更快的解决方案包括从 list1 制作 item->count 映射,并迭代 list2,同时更新映射和计数重复。不需要排序。需要额外一点额外的内存,但技术上是 O(l1+l2)。

答案 20 :(得分:-1)

要获取列表作为输出,请使用列表理解

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