Python中删除多个列表中的重复元素

5

我有三个列表X、Y、Z,如下所示:

X: [1, 1, 2, 3, 4, 5, 5, 5]
Y: [3, 3, 2, 6, 7, 1, 1, 2]
Z: [0, 0, 1, 1, 2, 3, 3, 4]

我正在尝试同时移除列表中具有相同索引的两个重复值,并获得如下减少的列表,这三个列表最初和最后的长度始终相同:

X: [2, 3, 4, 5]
Y: [2, 6, 7, 2]
Z: [1, 1, 2, 4]

我尝试使用zip(X, Y, Z)函数,但我无法对其进行索引,而dict.fromkeys仅删除其中一个重复项并将另一个留在新列表中。我希望能够同时删除两个。

非常感谢您的帮助!


4
我不理解你的逻辑,为什么第三个列表仍然有重复项?同时,似乎你正在随意删除一些值。 - user3483203
更重要的是,这个问题缺少一个 [mcve],以及你自己解决问题的尝试。 - user3483203
也许 ZZ: [2,4] - Druta Ruslan
1
啊,我现在明白了。他想要删除重复项,因为每个列表中相同的两个索引处有一对重复值。所以这里删除了0-1和5-6的索引。问题非常不清楚,但现在我理解了逻辑。 - user3483203
4个回答

5
使用 collections.Counterzip,您可以计算唯一的三元组。
然后通过生成器推导式去除重复项。
from collections import Counter

X = [1, 1, 2, 3, 4, 5, 5, 5]
Y = [3, 3, 2, 6, 7, 1, 1, 2]
Z = [0, 0, 1, 1, 2, 3, 3, 4]

c = Counter(zip(X, Y, Z))

X, Y, Z = zip(*(k for k, v in c.items() if v == 1))

print(X, Y, Z, sep='\n')

(2, 3, 4, 5)
(2, 6, 7, 2)
(1, 1, 2, 4)

请注意,如果有序计数是必需的且您未使用Python 3.6+,则可以通过子类化collections.OrderedDict来创建"OrderedCounter"。


1
请纠正我如果我错了,但这并不能保证三元组的顺序被保留 - 尽管三元组本身将被保留。我不是投票者,只是观察者。 - Jared Goguen
1
@JaredGoguen,好观点:在Python 3.6+中会有这个功能,而在<3.6中则没有。您可以构建一个OrderedCounter(子类化collections.OrderedDict),但不确定顺序是否是要求和OP的Python版本。 - jpp
1
这是 CPython 实现 的一个副作用,在 3.6 中通常情况下不能保证。但在 3.7 中将会得到保证。 - Jared Goguen
1
当然,我们甚至不知道是否需要按顺序保留 OP。 - Jared Goguen

1

对于这个任务,使用pandas库非常方便。只需使用列表创建数据帧,并应用df.drop_duplicateskeep=False(表示删除所有重复行):

import pandas as pd

dct = {
"X": [1, 1, 2, 3, 4, 5, 5, 5],
"Y": [3, 3, 2, 6, 7, 1, 1, 2],
"Z": [0, 0, 1, 1, 2, 3, 3, 4],
}
d = pd.DataFrame(dct)
d.drop_duplicates(keep=False)

0

不是最佳的方法

>>> from collections import Counter
>>> zipped_items = list(zip(x,y,z))
>>> counts = Counter(zipped_items)
>>> filtered_items = [item for item in zipped_items if counts[item] == 1]
>>> x1, y1, z1 = [ list(map(lambda x: x[i], filtered_items))
... for i in range(3)]

0
这是我的解决方案没有任何导入,但仍然简短易读:
X = [1, 1, 2, 3, 4, 5, 5, 5]
Y = [3, 3, 2, 6, 7, 1, 1, 2]
Z = [0, 0, 1, 1, 2, 3, 3, 4]

zipped = list(zip(X, Y, Z))
X, Y, Z = zip(*[i for i in zipped if zipped.count(i) == 1])
X, Y, Z = list(X), list(Y), list(Z)    

print(X, Y, Z, sep='\n')
# [2, 3, 4, 5]
# [2, 6, 7, 2]
# [1, 1, 2, 4]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接