python从2个列表中删除重复项

时间:2013-08-12 19:18:52

标签: python list duplicate-removal

我正在尝试从2个列表中删除重复项。所以我写了这个函数:

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']

如何修复我的功能以实现我的目标?

谢谢。

9 个答案:

答案 0 :(得分:26)

这是发生了什么。假设你有这个清单:

['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'?教训是:永远不要从正在循环的列表中删除元素。

答案 1 :(得分:12)

你的问题似乎是你正在改变你正在迭代的列表。相反,迭代列表的副本。

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']

答案 2 :(得分:10)

怎么样?
b= set(b) - set(a)

如果您需要b中可能的重复也在结果和/或要保留的顺序中重复出现,那么

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

会做的。

答案 3 :(得分:2)

您要求删除重复列表,这是我的解决方案:

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']

这里的好处是你保持两个列表项的顺序

答案 4 :(得分:1)

或一套

set(b).difference(a)
如果重要的话,预先警告的集合将不会保留顺序

答案 5 :(得分:1)

在迭代编辑列表时避免编辑列表问题的一种方法是使用理解:

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]

答案 6 :(得分:1)

您可以使用lambda函数。

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

从list1中删除list2中重复的元素。

>>> 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']

答案 7 :(得分:0)

关于“你怎么能修复它?”已经有很多答案了,所以这是一个“你怎么能改进它并且更加pythonic?”:因为你想要实现的是获得list {{之间的区别1}}和列表b,您应该对集合使用差异操作(operations on sets):

a

答案 8 :(得分:0)

沿着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']