我在Python中有一个列表列表,其定义如下:[[2, 3, 5], [3, 3, 1], [2, 3, 8]]
,不是我想要删除重复的条目,但重复我的意思是每个列表的前两个元素匹配,例如,第一个和第三个列表有2个和3个作为它们的第一个和第二个元素,因此,我将它视为重复,并且在删除后我想要有最终列表:[[2, 3, 5], [3, 3, 1]]
。目前,我有这样的事情:
arr = [[2, 3, 5], [3, 3, 1], [2, 3, 8]]
first = [item[0] for item in arr]
second = [item[1] for item in arr]
zipped = zip(first, second)
这将生成包含每个列表的前两个条目的元组列表。现在,我可以尝试获取重复条目的索引并从原始列表中删除这些索引。但是,有没有更短的方法来做我想要的?如果没有,这里获取重复索引的最佳方法是什么?
答案 0 :(得分:2)
您可以使用集来完成此任务:
arr = [[2, 3, 5], [3, 3, 1], [2, 3, 8]]
used = set()
[used.add(tuple(x[:2])) or x for x in arr if tuple(x[:2]) not in used]
返回
[[2, 3, 5], [3, 3, 1]]
used
中时才评估第一个表达式。结帐the docs on list comprehensions了解详情。set.add
总是返回None
。因此used.add(tuple(x[:2])) or x
始终评估为x
。list
不可用。最后,如果你不熟悉这种模式,@ wim就会提起来,这很难理解,并且在Python中可读性很重要。"因此,如果您正在编写将要共享的代码,请考虑将其更改为显式for
循环或使用其他方法。
答案 1 :(得分:2)
您可以使用collections.OrderedDict
进行订单保留重复数据删除:
>>> d = OrderedDict(((x[0], x[1]), x) for x in reversed(L))
>>> print(*d.values())
[2, 3, 5] [3, 3, 1]
要保留最后一个而不是第一个,只需删除reversed
:
>>> OrderedDict(((x[0], x[1]), x) for x in L).values()
odict_values([[2, 3, 8], [3, 3, 1]])
或使用普通的旧循环:
def dedupe(iterable):
seen = set()
for x in iterable:
first, second, *rest = x
if (first, second) not in seen:
seen.add((first, second))
yield x