2014-02-07 202 views
1

好吧,我有兩個列表,列表1和列表2.我想查找列表1和列表2中的所有項目,並將它們從列表1中刪除。我們曾想過這樣做是循環遍歷清單1,然後循環遍歷清單2,看它是否在清單2中,但在放大時似乎很慢並且效率低下。有沒有更有效的方法來做到這一點?比較兩個列表 - Python

此外,這些列表將按字母順序排列(它們是字符串),如果這有幫助的話。

我正在使用Python,但我也想從一般編程的角度思考。

list1 = ['bar','foo','hello','hi'] 
list2 = ['alpha','bar','hello','xam'] 

列表1將成爲['foo','hi']

+1

你可以使用'sets' – bnjmn

回答

6

在Python中,你可能會想用一組:

intersection = set(list1).intersection(list2) 

這將返回一個set這破壞了訂單(除其他事項外)但您隨時可以使用該設置來過濾list1

list1 = [x for x in list1 if x not in intersection] 

如果您真的想使用該集合,則該交集是最有用的。

set2 = set(list2) 
list1 = [x for x in list1 if x not in set2] 
+0

運用問題輸出樣本,這給了'''設置([ '酒吧', '你好'])'''這是不什麼海報想要。這個版本是否依賴? (我在2.7.6?) – wnnmaw

+0

實際上,你不需要交集,因爲你循環的所有元素都來自'list1'。 –

+0

@wnnmaw - 我最初誤解了OP的問題。我更新了在list-comp中添加'not'來獲得預期的輸出。 – mgilson

4

使用set得到兩者之間的區別:

list1 = ['bar','foo','hello','hi'] 
list2 = ['alpha','bar','hello','xam'] 

set1 = set(list1) 
set2 = set(list2) 
set1 - set2 

輸出:

正如評論指出的那樣,如果你不想一組在所有這不是確有必要
set(['hi', 'foo']) 

如上所述通過@chepner,使用set.difference,只有第一個需要被轉換成一組

set1.difference(list2) 

如果順序很重要,使他們的一個一組,並對比其他反對:

set2 = set(list2) 
[x for x in list1 if x not in set2] 

輸出:

['foo', 'hi'] 
+1

'-'是'差異'方法的運算符形式,因此您可以使用'set(list1).difference(list2)'來避免額外遍歷'list2'。 – chepner

+0

謝謝,爲此編輯。但不幸的是你不能做'set - list' – mhlester

1

下面是一個使用通用的解決方案編程方法,不使用集合,並沒有特別優化。它依賴於正在排序的兩個列表。

list1 = ['a', 'b', 'd', 'f', 'k'] 
list2 = ['c', 'd', 'i'] 
result = [] 

i1 = 0 
i2 = 0 
while i1 < len(list1) and i2 < len(list2): 
    # invariants: 
    # list1[i1] not in list2[:i2], and 
    # result == (list1[:i1] with elements of list2[:i2] omitted) 
    # 
    if list1[i1] < list2[i2]: 
     # By assumption, list1[i1] not in list2[:i2], 
     # and because list2 is sorted, the true 'if' condition 
     # implies that list1[i1] isn't in list2[i2:] either; 
     # that is, it isn't in list2 at all. 
     result.append(list1[i1]) 
     i1 += 1 
    elif list1[i1] > list2[i2]: 
     # can't decide membership of list1[i1] yet; 
     # advance to next element of list2 and loop again 
     i2 += 1 
    else: 
     # list1[i1] == list2[i2], so omit this element 
     i1 += 1 
     i2 += 1 

# Add any remaining elements of list1 to tail of result 
if i1 < len(list1): 
    result.extend(list1[i1:]) 

print(result) 

結果: ['a', 'b', 'f', 'k']