[英]python remove duplicates from 2 lists
I am trying to remove duplicates from 2 lists.我正在尝试从 2 个列表中删除重复项。 so I wrote this function:所以我写了这个 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
But I find that the matching items following a matched item does not get remove.但我发现匹配项后面的匹配项不会被删除。
I get result like this:我得到这样的结果:
found ijk
found opq
['lmn', 'rst', '123', '456']
but i expect result like this:但我期望这样的结果:
['123', '456'] ['123', '456']
How can I fix my function to do what I want?我怎样才能修复我的 function 来做我想做的事?
Thank you.谢谢你。
Here is what's going on.这是发生了什么。 Suppose you have this list:假设你有这个列表:
['a', 'b', 'c', 'd']
and you are looping over every element in the list.并且您正在遍历列表中的每个元素。 Suppose you are currently at index position 1:假设您当前位于索引位置 1:
['a', 'b', 'c', 'd']
^
|
index = 1
...and you remove the element at index position 1, giving you this: ...然后您删除索引位置 1 处的元素,为您提供:
['a', 'c', 'd']
^
|
index 1
After removing the item, the other items slide to the left, giving you this:删除项目后,其他项目向左滑动,为您提供:
['a', 'c', 'd']
^
|
index 1
Then when the loop runs again, the loop increments the index to 2, giving you this:然后当循环再次运行时,循环将索引增加到 2,给你这个:
['a', 'c', 'd']
^
|
index = 2
See how you skipped over 'c'?看看你是如何跳过“c”的? The lesson is: never delete an element from a list that you are looping over.教训是:永远不要从您正在循环的列表中删除元素。
Your problem seems to be that you're changing the list you're iterating over.您的问题似乎是您正在更改正在迭代的列表。 Iterate over a copy of the list instead.而是迭代列表的副本。
for i in b[:]:
if i in a:
b.remove(i)
>>> b
['123', '456']
But, How about using a list comprehension instead?但是,如何使用列表理解来代替?
>>> 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']
What about关于什么
b= set(b) - set(a)
If you need possible repetitions in b
to also appear repeated in the result and/or order to be preserved, then如果您需要b
可能的重复也出现在结果和/或要保留的顺序中重复,那么
b= [ x for x in b if not x in a ]
would do.会做。
You asked to remove both the lists duplicates , here's my solution:您要求删除两个列表重复项,这是我的解决方案:
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()
Result:结果:
['abc', 'def', 'xyz']
['123', '456']
The nice thing here is that you keep the order of both lists items这里的好处是您保持两个列表项的顺序
or a set或一组
set(b).difference(a)
be forewarned sets will not preserve order if that is important预先警告如果这很重要,集合将不会保留顺序
One way of avoiding the problem of editing a list while you iterate over it, is to use comprehensions:避免在迭代列表时编辑列表问题的一种方法是使用推导式:
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]
You can use lambda functions.您可以使用 lambda 函数。
f = lambda list1, list2: list(filter(lambda element: element not in list2, list1))
The duplicated elements in list2 are removed from 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']
You can use the list comprehensive您可以使用列表综合
a = ["abc", "def", "ijk", "lmn", "opq", "rst", "xyz"]
b = ["ijk", "lmn", "opq", "rst", "123", "456", ]
duplicates value removed from a从 a 中删除的重复值
c=[value for value in a if value not in b]
duplicate value removed from b从 b 中删除重复值
c=[value for value in b if value not in a]
There are already many answers on "how can you fix it?", so this is a "how can you improve it and be more pythonic?": since what you want to achieve is to get the difference between list b
and list a
, you should use difference operation on sets ( operations on sets ):已经有很多关于“你如何修复它?”的答案,所以这是一个“你如何改进它并变得更加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'])
Along the lines of 7stud, if you go through the list in reversed order, you don't have the problem you encountered:沿着 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']
A simple fix would be to instead iterate through a range, look at the element at the index, delete that element, then decrement the counter by 1.一个简单的解决方法是迭代一个范围,查看索引处的元素,删除该元素,然后将计数器减 1。
Mock untested code模拟未经测试的代码
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.