2011-06-16 39 views
4

我想在Python(2.7)中交叉兩個列表。我需要的結果是迭代:Python列表交集效率:generator還是filter()?

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) 

使用過濾器():

result = filter(lambda x: x in list2, list1) 

其他建議?

由於提前,
阿姆農

回答

14

這些都不。最好的方法是使用集合。

list1 = [1,2,3,4] 
list2 = [3,4,5,6] 
result = set(list1).intersection(list2) 

集合是可迭代的,因此不需要將結果轉換爲任何東西。

+1

有趣的是,'set(list1)。相交(列表2)'比'set(list1)&set(列表2)'更快,我猜這是因爲創建兩個集合比加載和調用'.intersection()'hmm更加昂貴.. – mouad 2011-06-16 09:32:42

+0

@mouad在我的機器,'set(list1)&set(list2)'比使用'.intersection()'快。但差異不是很顯着。 – pemistahl 2013-02-16 17:50:41

+0

這是否需要列表進行排序? – Youda008 2016-11-15 09:51:43

7

您的解決方案的複雜度爲O(m*n),其中mn是兩個列表的相應長度。可以提高複雜O(m+n)使用一組的列表之一:

s = set(list1) 
result = [x for x in list2 if x in s] 

在速度比可讀性(即,幾乎沒有),更重要的情況下,也可以使用

result = filter(set(a).__contains__, b) 

比我機器上的其他解決方案快大約20%。

0

對列表的情況下,最有效的方法是使用:

result = set(list1).intersection(list2) 

提到,但numpy的陣列,intersection1d功能更高效:

import numpy as np 
result = np.intersection1d(list1, list2) 

尤其是,當你知道該列表沒有重複值,您可以將其用作:

result = np.intersection1d(list1, list2, assume_unique=True)