簡體   English   中英

python 從 2 個列表中刪除重復項

[英]python remove duplicates from 2 lists

我正在嘗試從 2 個列表中刪除重復項。 所以我寫了這個 function:

a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]

b = ["ijk", "lmn", "opq", "rst", "123", "456", ]

for i in b:
    if i in a:
        print "found " + i
        b.remove(i)

print b

但我發現匹配項后面的匹配項不會被刪除。

我得到這樣的結果:

found ijk
found opq
['lmn', 'rst', '123', '456']

但我期望這樣的結果:

['123', '456']

我怎樣才能修復我的 function 來做我想做的事?

謝謝你。

這是發生了什么。 假設你有這個列表:

['a', 'b', 'c', 'd']

並且您正在遍歷列表中的每個元素。 假設您當前位於索引位置 1:

['a', 'b', 'c', 'd']
       ^
       |
   index = 1

...然后您刪除索引位置 1 處的元素,為您提供:

['a',      'c', 'd']
       ^
       |
    index 1

刪除項目后,其他項目向左滑動,為您提供:

['a', 'c', 'd']
       ^
       |
    index 1

然后當循環再次運行時,循環將索引增加到 2,給你這個:

['a', 'c', 'd']
            ^ 
            |
         index = 2

看看你是如何跳過“c”的? 教訓是:永遠不要從您正在循環的列表中刪除元素。

您的問題似乎是您正在更改正在迭代的列表。 而是迭代列表的副本。

for i in b[:]:
    if i in a:
        b.remove(i)


>>> b
['123', '456']

但是,如何使用列表理解來代替?

>>> a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
>>> b = ["ijk", "lmn", "opq", "rst", "123", "456", ]
>>> [elem for elem in b if elem not in a ]
['123', '456']

關於什么

b= set(b) - set(a)

如果您需要b可能的重復也出現在結果和/或要保留的順序中重復,那么

b= [ x for x in b if not x in a ] 

會做。

您要求刪除兩個列表重復項,這是我的解決方案:

from collections import OrderedDict
a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
b = ["ijk", "lmn", "opq", "rst", "123", "456", ]

x = OrderedDict.fromkeys(a)
y = OrderedDict.fromkeys(b)

for k in x:
    if k in y:
        x.pop(k)
        y.pop(k)


print x.keys()
print y.keys()

結果:

['abc', 'def', 'xyz']
['123', '456']

這里的好處是您保持兩個列表項的順序

或一組

set(b).difference(a)

預先警告如果這很重要,集合將不會保留順序

避免在迭代列表時編輯列表問題的一種方法是使用推導式:

a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
b = ["ijk", "lmn", "opq", "rst", "123", "456", ]
b = [x for x in b if not x in a]

您可以使用 lambda 函數。

f = lambda list1, list2: list(filter(lambda element: element not in list2, list1))

list2 中的重復元素從 list1 中刪除。

>>> a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
>>> b = ["ijk", "lmn", "opq", "rst", "123", "456"]
>>> f(a, b)
['abc', 'def', 'xyz']
>>> f(b, a)
['123', '456']

您可以使用列表綜合

a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
b = ["ijk", "lmn", "opq", "rst", "123", "456", ]

從 a 中刪除的重復值

c=[value for value in a if value not in b]

從 b 中刪除重復值

c=[value for value in b if value not in a]

已經有很多關於“你如何修復它?”的答案,所以這是一個“你如何改進它並變得更加pythonic?”:因為你想要實現的是獲得 list b和 list a之間的區別,您應該對集合使用差異操作(對集合的操作):

>>> a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
>>> b = ["ijk", "lmn", "opq", "rst", "123", "456", ]
>>> s1 = set(a)
>>> s2 = set(b)
>>> s2 - s1
set(['123', '456'])

沿着 7stud 的路線,如果您以相反的順序瀏覽列表,則不會遇到您遇到的問題:

a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]

b = ["ijk", "lmn", "opq", "rst", "123", "456", ]

for i in reversed(b):
    if i in a:
        print "found " + i
        b.remove(i)

print b

Output:
found rst
found opq
found lmn
found ijk
['123', '456']

a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]

b = ["ijk", "lmn", "opq", "rst", "123", "456","abc"]

for i in a:
    if i in b:
        print("found", i)
        b.remove(i)
print(b)

output:
found abc
found ijk
found lmn
found opq
found rst
['123', '456']

一個簡單的解決方法是迭代一個范圍,查看索引處的元素,刪除該元素,然后將計數器減 1。
模擬未經測試的代碼

for i in range(0, len(b)):
    if b[i] in a:
        del b[i]
        i -= 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM