所以我有两个int列表xs和ys(任意长度),并希望有效地删除每个列表中出现的重复项。由于您无法在循环播放列表时编辑列表,因此我的尝试是:
matches = [match for match in xs if match in ys]
for match in matches:
xs.remove(match)
ys.remove(match)
但重要的是,如果值在xs中出现两次但在ys中出现一次,则会产生错误,因为"如果匹配在ys"对于相同的值,求值为true两次,但我需要它只计算一次。
所以澄清,如果:
xs = [0, 2, 4, 8, 8, 100]
ys = [1, 3, 5, 8, 8, 8, 10]
然后需要从两个列表中删除8次。
我该如何有效地做到这一点?感谢
编辑:列表不一定是有序的,实际上两个列表都可能包含重复项。
答案 0 :(得分: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])]
请注意,这仅适用于您的元素是可以清除的。