如何比较python中的两个列表并返回匹配项

teh*_*yan 349 python list

我想获取两个列表并找到两者中出现的值.

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

returnMatches(a, b)
Run Code Online (Sandbox Code Playgroud)

[5]例如,会回来.

Sil*_*ost 435

不是最有效的方法,但到目前为止最明显的方法是:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}
Run Code Online (Sandbox Code Playgroud)

如果订单很重要,你可以使用这样的列表推导来做到这一点:

>>> [i for i, j in zip(a, b) if i == j]
[5]
Run Code Online (Sandbox Code Playgroud)

(仅适用于大小相同的列表,其中含义为重要性).

  • 另一个需要注意的事项是:列表推导会找到在两个位置出现的值(这是SilentGhost所说的"order is significant").集合交叉解决方案还将在不同位置找到匹配.这些是两个完全不同的问题的答案......(该问题的含义模糊不清) (17认同)
  • 需要注意的是,列表理解*不一定是更快的选择.对于较大的集合(性能最可能很重要),按位比较(`&`)或`set(a).intersection(b)`将比列表理解快或快. (12认同)
  • 第一个示例```set(a)&set(b)```的时间复杂度是多少? (2认同)
  • 例如,如何找到列表 A 中但不在列表 B 中的项目? (2认同)

小智 369

使用set.intersection(),它快速且可读.

>>> set(a).intersection(b)
set([5])
Run Code Online (Sandbox Code Playgroud)

  • 这个答案具有良好的算法性能,因为只有一个列表(更短的应该是首选)被转换为快速查找的集合,而另一个列表遍历查找集合中的项目. (27认同)
  • `bool(set(a).intersection(b))`用于'True`或'False` (14认同)
  • 这个答案更灵活,更易读,因为人们可能需要[`difference`](https://docs.python.org/3/library/stdtypes.html#frozenset.difference)或[`union`](https:/ /docs.python.org/3/library/stdtypes.html#frozenset.union). (6认同)

Jos*_*ker 98

快速性能测试显示Lutz的解决方案是最好的:

import time

def speed_test(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        for x in xrange(5000):
            results = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return results
    return wrapper

@speed_test
def compare_bitwise(x, y):
    set_x = frozenset(x)
    set_y = frozenset(y)
    return set_x & set_y

@speed_test
def compare_listcomp(x, y):
    return [i for i, j in zip(x, y) if i == j]

@speed_test
def compare_intersect(x, y):
    return frozenset(x).intersection(y)

# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)
Run Code Online (Sandbox Code Playgroud)

这些是我的机器上的结果:

# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms

# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms
Run Code Online (Sandbox Code Playgroud)

显然,任何人工性能测试都应该采取一些措施,但由于set().intersection()答案至少与其他解决方案一样快,并且也是最易读的,因此它应该是这个常见问题的标准解决方案.


Sin*_*ion 61

我更喜欢基于集合的答案,但这里的答案仍然适用

[x for x in a if x in b]
Run Code Online (Sandbox Code Playgroud)


Gre*_*ill 12

最简单的方法是使用集合:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
Run Code Online (Sandbox Code Playgroud)


Dis*_*sie 12

快捷方式:

list(set(a).intersection(set(b)))
Run Code Online (Sandbox Code Playgroud)


小智 12

>>> s = ['a','b','c']   
>>> f = ['a','b','d','c']  
>>> ss= set(s)  
>>> fs =set(f)  
>>> print ss.intersection(fs)   
   **set(['a', 'c', 'b'])**  
>>> print ss.union(fs)        
   **set(['a', 'c', 'b', 'd'])**  
>>> print ss.union(fs)  - ss.intersection(fs)   
   **set(['d'])**
Run Code Online (Sandbox Code Playgroud)


mus*_*fiq 9

您也可以通过将新元素保存在新列表中来尝试此操作.

new_list = []
for element in a:
    if element in b:
        new_list.append(element)
Run Code Online (Sandbox Code Playgroud)


Tim*_*ley 5

你想要重复吗?如果不是,也许您应该使用集合:


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])
Run Code Online (Sandbox Code Playgroud)


小智 5

检查对象1的深度为1且保持顺序的列表1(lst1)和列表2(lst2)的列表相等性的另一种实用方式是:

all(i == j for i, j in zip(lst1, lst2))   
Run Code Online (Sandbox Code Playgroud)


Sup*_*ova 5

也可以使用 itertools.product。

>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
...     if i[0] == i[1]:
...         common_elements.append(i[0])
Run Code Online (Sandbox Code Playgroud)


Pav*_*man 5

寻找共同价值观的另一种方法:

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
matches = [i for i in a if i in b]
Run Code Online (Sandbox Code Playgroud)