Python 在列表中保留首次发现的重复项
我有一个如下列表:Python 在列表中保留首次发现的重复项,python,list,python-2.7,Python,List,Python 2.7,我有一个如下列表: [(1, 0.3), (3, 0.2), (3, 0.15), (1, 0.07), (1, 0.02), (2, 0.01)] 我希望根据每个元组中的第一个项,保留此列表中第一个找到的重复项: [(1, 0.3), (3, 0.2), (2, 0.01)] 有没有一种有效的方法可以做到这一点?如果结果列表的顺序无关紧要,只是它包含每个元组原始列表中的第一个条目:首先反转列表,然后通过dict删除重复项,并保留每个键的最后一个条目(原始列表中的第一个,因为它被颠倒了):
[(1, 0.3), (3, 0.2), (3, 0.15), (1, 0.07), (1, 0.02), (2, 0.01)]
我希望根据每个元组中的第一个项,保留此列表中第一个找到的重复项:
[(1, 0.3), (3, 0.2), (2, 0.01)]
有没有一种有效的方法可以做到这一点?如果结果列表的顺序无关紧要,只是它包含每个元组原始列表中的第一个条目:首先反转列表,然后通过
dict
删除重复项,并保留每个键的最后一个条目(原始列表中的第一个,因为它被颠倒了):
如果结果列表的顺序很重要,请参见Padraic的答案:)如果使用生成器函数,则可以延迟返回第一个副本,只需存储密钥,一旦函数结束,这些密钥将被gc:
def first_found(l):
seen = set()
for k, v in l:
if k not in seen:
yield (k, v)
seen.add(k)
在您的列表中,您可以看到:
print(list(first_found(l)))
[(1, 0.3), (3, 0.2), (2, 0.01)]
或更新原始列表:
l[:] = first_found(l)
或创建一个dict:
od = OrderedDict(first_found(l))
print(od)
OrderedDict([(1, 0.3), (3, 0.2), (2, 0.01)])
这将不会保持元素的原始顺序。除此之外,它会很好用的,很好。我将答案更新为使用
reversed()
。在Python3上,与使用for循环相比,此解决方案不会有更多的副本。在Python2上,如果将items()
替换为iteritems()
,那么就不会有比使用for循环更多的副本了。这一点很好–考虑到无论如何都会复制列表,我已经将lastdupdateordereddict
示例还原为只使用[:-1]
来反转列表。OrderedDict
直接支持对象上的reversed()!
od = OrderedDict(first_found(l))
print(od)
OrderedDict([(1, 0.3), (3, 0.2), (2, 0.01)])