2017-02-22 71 views
1

請不要給我減。我想問一個更好的方法來解決這個問題,因爲我現在正在爲我成爲一個巨大的負擔。Python:更好的方法來比較兩個列表?

Hier是我的問題:我有兩個列表。我想確保一個列表中沒有項目在另一個列表中。

在Python我一直在與下面的行...(假設List_s有3項)。

if List_s[0] not in List_big and List_s[1] not in List_big and List_s[2] not in List_big: #none item from List_s should be in List_big 
    do something 
else: 
    pass 

這些線路實際上是爲我好,直到我突然意識到我有工作列表長度> 200。我有很多名單可供比較。

那麼我該如何更改代碼呢?非常感謝您的幫助!

+3

'any(x in List_big for x in List_s)'雖然這將是一個多項式時間。可能更好地從'List_big'中創建一個'set',這樣可以是線性時間。 –

回答

2

您可以將列表的一至set和使用set.intersection

if not set(List_s).intersection(List_big): 
    print('no common items between lists') 

注意,在兩個列表中的元素必須是hashable

+0

如果元素是可散列的。 –

+0

感謝@PaulPanzer,更新。 – krock

+1

謝謝!這比我的好! – doglas

1

對於非常大名單,

import timeit 
import random 

L=[random.randrange(2000000) for x in xrange(1000000)] 
M=[random.randrange(2000000) for x in xrange(1000000)] 

start_time = timeit.default_timer() 
print any(x in M for x in L) 
#True 
print timeit.default_timer() - start_time 
#0.00981207940825 

start_time = timeit.default_timer() 
print not set(L).isdisjoint(M) 
#True 
print timeit.default_timer() - start_time 
#0.164795298542 

start_time = timeit.default_timer() 
print True if set(L) & set(M) else False 
#True 
print timeit.default_timer() - start_time 
#0.436377859225 

start_time = timeit.default_timer() 
print True if set(L).intersection(M) else False 
#True 
print timeit.default_timer() - start_time 
#0.368563831022 

顯然,

print any(x in M for x in L) 

是更有效

+0

非常感謝! – doglas

2

你會得到相同的結果,不管你使用:

set(List_s).isdisjoint(List_big) 

或者:

not set(List_s).intersection(List_big) 

但是set.isdisjoint要快得多。在我的計算機上,isdisjoint需要大約150納秒才能對測試數據運行,而intersection需要95微秒才能運行相同的數據 - 約慢了630倍!

+0

謝謝你的提示! – doglas