过滤python中的元组列表

时间:2012-05-21 09:51:50

标签: python

我正在寻找一种干净的pythonic方式来做以下事情

我有一个元组列表说:

[(1,'a'), (1,'b'), (1,'c'), (2, 'd'), (5, 'e'), (5, 'f')]

我想创建一个新列表,丢弃之前已经看过第一个键的元组。所以上面的o / p将是:

[(1,'c'), (2,'d'), (5, 'f')]

谢谢!

3 个答案:

答案 0 :(得分:4)

一种简单的方法是创建一个字典,因为它只保留最后一个元素具有相同的键:

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在评论中提及,由于字典项目的顺序无法保证,您可能想要使用ordered dictionary

from collections import OrderedDict
newl = OrderedDict(l).items()

如果你真的想要保持第一个元组使用相同的键(而不是最后一个,你的问题是不明确的),那么你可以先颠倒列表,添加它做字典并反转{{1}的输出再次。
虽然在这种情况下可能有更好的方法来实现这一目标。

答案 1 :(得分:2)

使用unique_everseen docs

中的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')]

答案 2 :(得分:2)

一个漂亮的伎俩,一个班轮恋物癖保持秩序(我承认它不是很可读,但你知道......)

>>> 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')]