次のことを行うきれいな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()
。
その場合、おそらくこれを達成するためのより良い方法がありますが。
ドキュメント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')]
ワンライナーフェティシストが順番を維持するための気の利いたトリックです(あまり読みにくいことは認めますが...)
>>> 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')]