2012-05-21 53 views
1

正在尋找做以下過濾在python元組的列表

我有一個元組列表的清潔Python的方式說:

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

我想讓它丟棄元組的新名單他的第一把鑰匙已經見過了。所以上面的o/p是:

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

謝謝!

+2

嗯,你的例子似乎不匹配描述。 – georg

回答

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() 

如果你真的想保持使用相同的密鑰的第一個元組(而不是最後一個,你我的問題),那麼你可以先反轉列表,添加它做字典並再次反轉.items()的輸出。
雖然在這種情況下,可能有更好的方法來實現這一點。

+0

其實我相信這應該是'OrderedDict'而不是簡單的'dict',並且你應該轉換'l [:: -1]'(或'revers(l)')而不是'l'。這樣OP的要求(「_discards元組的第一個鍵已經被看到過了」)將會被滿足,並且命令將被保留。 – Tadeck

+0

@Tadeck:有關OrderedDict的好處。至於這個問題的措辭,我認爲這是不明確的。如果他想保留'[(1,'a'),(2,'d'),(5,'e')]',那麼是的,可以簡單地顛倒這個列表。 –

+0

如果您將該列表倒過來,那麼使用OrderedDict不會幫助保持訂單。然而,OP似乎對他們想要的東西感到困惑。 – Duncan

2

使用unique_everseenitertoolsdocs

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

一個襯墊癖一個漂亮的把戲,保持在發生的順序(我承認這不是很可讀,但你知道... )

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