>>> from itertools import groupby
>>> L = [3,5,0,6,8,9,7,0,1,0]
>>> [list(g) for k, g in groupby(L, key=bool) if k]
[[3, 5], [6, 8, 9, 7], [1]]
key=bool
は空0
と見なされるため、この場合は機能しますが、@ AshwiniChaudhary が指摘したように、たとえばによって分割しない場合は、カスタム関数を使用する必要があります。で割るkey
0
2
key=lambda x: x != 2
説明:
最初に、どのように機能するかを説明しますkey
。
>>> bool(3), bool(5)
(True, True)
>>> bool(0)
False
ご覧のとおり、それ以外の場合は、またはがTrue
返されます。(実際には、他の空の組み込みオブジェクトと同様にreturn も返しますが、ここでは数値のみを考慮しています)False
False
0
True
bool('')
bool([])
False
関数groupby
の結果をグループ化するだけなので、 s とs のグループになります。key
0
1
>>> [(key, group) for key, group in groupby(L, key=bool)]
[(True, <itertools._grouper object at 0xb6fc1dac>), (False, <itertools._grouper object at 0xb6fc432c>), (True, <itertools._grouper object at 0xb6fc422c>), (False, <itertools._grouper object at 0xb6fc4c2c>), (True, <itertools._grouper object at 0xb6fc428c>), (False, <itertools._grouper object at 0xb6fc476c>)]
しかし、ご覧のとおり、グループは奇妙なオブジェクト、itertools._grouper
オブジェクトです。リストを返さないのはなぜですか?itertools
アイテムを遅延してグループ化する方がはるかに効率的ですが、グループ内のすべてのアイテムをlist
.
>>> [(key, list(group)) for key, group in groupby(L, key=bool)]
[(True, [3, 5]), (False, [0]), (True, [6, 8, 9, 7]), (False, [0]), (True, [1]), (False, [0])]
ただし、 は必要ありません。そうであるkey
かどうかを確認し、True
この述語を満たすアイテムのみを返す必要があるだけです。これが最初の私の答えにつながります。
>>> [list(group) for key, group in groupby(L, key=bool) if key]
[[3, 5], [6, 8, 9, 7], [1]]