2017-03-05 31 views
1

所以我有兩個int列出X和Y(任意長度的),並希望刪除有效地出現在每個列表中的重複。既然你不能/不應該通過它編輯列表會循環,我的嘗試是:查找並從兩個列表在Python除去比賽

matches = [match for match in xs if match in ys] 
for match in matches: 
    xs.remove(match) 
    ys.remove(match) 

但重要的,如果值XS但一旦YS出現兩次,這會產生一個錯誤,因爲「如果ys匹配」對於相同的值計算結果爲兩次,但我需要它只計算一次。

所以要澄清,如果:

xs = [0, 2, 4, 8, 8, 100] 
ys = [1, 3, 5, 8, 8, 8, 10] 

然後8個需要從兩個列表中刪除兩次。

我怎麼能這樣做有效地?由於

編輯:列表不一定排序並在實踐中這兩個列表都可能含有重複。

回答

4

您可以使用該路口多集(collections.Counter)。如果您期望有大量重複項目且列表很大,則建議避免.remove,因爲它很貴。列表理解能力更好。我們使用一些適度的itertools欺騙來過濾出標記的重複項。請注意,這可能會有所調整,例如不刪除第一個,而是過去的事件等

from collections import Counter 
from itertools import repeat, chain 

xc = Counter(xs) 
yc = Counter(ys) 
matches = xc & yc 
tr = repeat(True) 
rm = {k: chain(repeat(False, m), tr) for k, m in matches.items()} 
xs = [x for x in xs if not x in rm or next(rm[x])] 
rm = {k: chain(repeat(False, m), tr) for k, m in matches.items()} 
ys = [y for y in ys if not y in rm or next(rm[y])] 

請注意,這僅適用,如果你的元素是可哈希。

+1

它適用於只有2個重複,但不n個重複,已經更新了例子來說明這 –

+0

@BenJones啊,我明白了。你能澄清嗎?在這種情況下應該發生什麼:'xs = [1,1,1,1,2]''ys = [1,1,3]'?期望的輸出? 'xs = [1,1,1,2]''ys = [1,3']?或'xs = [1,1,2]''ys = [3]'或'xs = [1,2]''ys = [3]'? –

+0

這兩個列表中共有兩個1,因此期望的輸出是xs = [1,1,2]和ys = [3],對於混淆抱歉! –