3

我必须操作的列表更长,但例如让我们使用一个 [3,5,0,6,8,9,7,0,1,0]. 零之间的元素数量不是恒定的。我想将零之前的术语分组到子列表中。我正在寻找的是[[3,5],[6,8,9,7],[1]]; 零拆分术语但不包含在子列表中。

我认为我不能使用该split功能,因为我正在对元素进行分组,所以我一直试图找出一种以这种方式进行分组的方法。

4

2 回答 2

6
>>> 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它被认为是key的,但正如@AshwiniChaudhary 指出的那样,当您不通过0例如拆分时,您将不得不使用自定义函数。分裂2

key=lambda x: x != 2

解释:

首先,我将说明其key工作原理:

>>> bool(3), bool(5)
(True, True)
>>> bool(0)
False

如您所见,它将返回TrueFalse, Falseon0True其他任何东西。(实际上bool('')也是bool([])return False,以及任何其他空的内置对象,但我们在这里只考虑数字)

所以groupby只是对key函数的结果进行分组,因此是0s 和1s 的组。

>>> [(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]]
于 2013-06-02T01:24:14.017 回答
1

一个比较可笑的单行版本:

>>> L = [3,5,0,6,8,9,7,0,1,0]
>>> [ map(int, str(r)) for r in "".join([str(r) for r in L]).rstrip("0").split("0") ]
[[3, 5], [6, 8, 9, 7], [1]]

虽然没有导入新模块。

于 2013-06-02T01:50:58.540 回答