我想在Python(2.7)中交叉两个列表。我需要结果可迭代:
list1 = [1,2,3,4]
list2 = [3,4,5,6]
result = (3,4) # any kind of iterable
提供完整迭代将在交叉点后首先执行,以下哪项更有效?
使用发电机:
result = (x for x in list1 if x in list2)
使用filter():
result = filter(lambda x: x in list2, list1)
其他建议?
提前致谢,
暗嫩
答案 0 :(得分:17)
这些都不是。最好的方法是使用集合。
list1 = [1,2,3,4]
list2 = [3,4,5,6]
result = set(list1).intersection(list2)
集合是可迭代的,因此无需将结果转换为任何内容。
答案 1 :(得分:7)
您的解决方案的复杂度为O(m*n)
,其中m
和n
是两个列表的相应长度。您可以使用其中一个列表的集合来提高O(m+n)
的复杂性:
s = set(list1)
result = [x for x in list2 if x in s]
如果速度比可读性更重要(即几乎从不),您也可以使用
result = filter(set(a).__contains__, b)
比我机器上的其他解决方案快20%左右。
答案 2 :(得分:1)
对于列表的情况,最有效的方法是使用:
result = set(list1).intersection(list2)
如上所述,但对于numpy数组,intersection1d
函数效率更高:
import numpy as np
result = np.intersection1d(list1, list2)
特别是,当您知道列表没有重复值时,您可以将其用作:
result = np.intersection1d(list1, list2, assume_unique=True)
答案 3 :(得分:0)
我试图比较3种列表交集方法的速度:
import random
a = [random.randint(0, 1000) for _ in range(1000)]
b = [random.randint(0, 1000) for _ in range(1000)]
经过时间: 8.95265507698059
import time
start = time.time()
for _ in range(1000):
result = [x for x in a if x in b]
elapse = time.time() - start
print(elapse)
经过时间: 0.09089064598083496
start = time.time()
for _ in range(1000):
result = set.intersection(set(a), set(b))
elapse = time.time() - start
print(elapse)
经过的时间: 0.323300838470459
start = time.time()
for _ in range(1000):
result = np.intersect1d(a, b)
elapse = time.time() - start
print(elapse)
我认为使用set.intersection
是最快的方法。