0

I have a list

l=[(1,2),(1,6),(3,4),(3,6),(1,4),(4,3)]

I want to return a list that contains lists by the first number in each tuple. Something like this:

[[2,4,6],[4,6],[3]]

To make a program that iterates on list and writing a whole function that does it is easy. I want to find a oneliner - python way of doing it. Any ideas?

4

2 に答える 2

10
>>> from itertools import groupby
>>> from operator import itemgetter
>>> L = [(1,2), (1,6), (3,4), (3,6), (1,4), (4,3)]
>>> [[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
[[2, 4, 6], [4, 6], [3]]

説明

これは を使用して機能しitertools.groupbyます。iterable で連続groupbyするグループを検索し、キーとグループのペアを介して反復子を返します。

に与えられた引数は、タプルごとに呼び出されるgroupbyキー関数で、最初の項目を のキーとして返します。itemgetter(0)groupby

groupby要素を元の順序でグループ化するため、リストの最初の番号でグループ化する場合はgroupby、最初の番号を昇順に並べ替えて実際にグループ化できるように、最初に並べ替える必要があります。

>>> sorted(L)
[(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (4, 3)]

最終出力を振り返ると、作成されるグループを明確に確認できるソートされたリストがあります。groupbyを使用して、キー、グループのペアを表示できるようになりました。

[(1, <itertools._grouper object at 0x02BB7ED0>), (3, <itertools._grouper object at 0x02BB7CF0>), (4, <itertools._grouper object at 0x02BB7E30>)]

これは、最初の番号でグループ化されたソート済みアイテムです。groupby各キーのグループをイテレータとして返します。これは非常に効率的ですが、この例では、list適切に機能することを確認するために単に に変換します。

>>> [(k, list(v)) for k,v in groupby(sorted(L), itemgetter(0))]
[(1, [(1, 2), (1, 4), (1, 6)]), (3, [(3, 4), (3, 6)]), (4, [(4, 3)])]

これはほとんど正しいことですが、必要な出力には、各リストのグループの 2 番目の数字しか表示されません。したがって、以下は望ましい結果を達成します。

[[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
于 2012-05-28T12:51:44.123 に答える
2
l = [(1, 2), (1, 6), (3, 4), (3, 6), (1, 4), (4, 3)]

d = {}
for (k, v) in l:
    d.setdefault(k, []).append(v)

print d.values()

ワンライナーではないことはわかっていますが、おそらくワンライナーよりも読みやすいでしょう。

于 2012-05-28T13:23:46.890 に答える