我正在寻找一种干净的pythonic方式来执行以下操作
我有一个元组列表说:
[(1,'a'), (1,'b'), (1,'c'), (2, 'd'), (5, 'e'), (5, 'f')]
我想创建一个新列表,它丢弃以前见过第一个键的元组。所以上面的 o/p 将是:
[(1,'c'), (2,'d'), (5, 'f')]
谢谢!
我正在寻找一种干净的pythonic方式来执行以下操作
我有一个元组列表说:
[(1,'a'), (1,'b'), (1,'c'), (2, 'd'), (5, 'e'), (5, 'f')]
我想创建一个新列表,它丢弃以前见过第一个键的元组。所以上面的 o/p 将是:
[(1,'c'), (2,'d'), (5, 'f')]
谢谢!
一个简单的方法是创建一个字典,因为它只会保留最后一个元素具有相同的键:
In [1]: l = [(1,'a'), (1,'b'), (1,'c'), (2, 'd'), (5, 'e'), (5, 'f')]
In [2]: dict(l).items()
Out[2]: [(1, 'c'), (2, 'd'), (5, 'f')]
更新:正如@Tadeck在他的评论中提到的那样,由于不能保证字典项目的顺序,您可能想要使用有序字典:
from collections import OrderedDict
newl = OrderedDict(l).items()
如果你真的想用相同的键保留第一个元组(而不是最后一个,你的问题是模棱两可的),那么你可以先反转列表,添加它做字典并.items()
再次反转输出。
尽管在这种情况下可能有更好的方法来实现这一点。
对于一个班轮迷恋者来说,这是一个很好的技巧,可以保持订单到位(我承认它不是很可读,但你知道......)
>>> s = [(1,'a'), (1,'b'), (1,'c'), (2, 'd'), (5, 'e'), (5, 'f')]
>>> seen = set()
>>> [seen.add(x[0]) or x for x in s if x[0] not in seen]
[(1, 'a'), (2, 'd'), (5, 'e')]
unique_everseen
从文档中使用itertools
from itertools import ifilterfalse
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in ifilterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
a = [(1,'a'), (1,'b'), (1,'c'), (2, 'd'), (5, 'e'), (5, 'f')]
print list(unique_everseen(a,key=lambda x: x[0]))
屈服
[(1, 'a'), (2, 'd'), (5, 'e')]