itertools groupby对象未正确输出

时间:2018-02-07 02:43:13

标签: python iterator grouping itertools

我试图使用itertools.groupby来帮助我按正面或负面属性对整数列表进行分组,例如:

输入

[1,2,3, -1,-2,-3, 1,2,3, -1,-2,-3] 

将返回

[[1,2,3],[-1,-2,-3],[1,2,3],[-1,-2,-3]]

但是如果我:

import itertools

nums = [1,2,3, -1,-2,-3, 1,2,3, -1,-2,-3]
group_list = list(itertools.groupby(nums, key=lambda x: x>=0))
print(group_list)
for k, v in group_list:
    print(list(v))
>>>
[]
[-3]
[]
[]

但如果我没有list() groupby对象,它将正常工作:

nums = [1,2,3, -1,-2,-3, 1,2,3, -1,-2,-3]
group_list = itertools.groupby(nums, key=lambda x: x>=0)
for k, v in group_list:
    print(list(v))
>>>
[1, 2, 3]
[-1, -2, -3]
[1, 2, 3]
[-1, -2, -3]

我不明白的是,groupby对象是由一对key和_grouper对象组成的迭代器,groupby对象的list()调用不应该使用{{1对象?

即使它确实消耗了,我如何从第二个元素中获得_grouper

1 个答案:

答案 0 :(得分:3)

the docs,明确指出推进groupby对象会导致前一个组无法使用(实际上是空的):

  

返回的组本身就是一个迭代器,它与groupby()共享底层的iterable。由于源是共享的,因此当groupby()对象前进时,前一个组不再可见。因此,如果以后需要该数据,则应将其存储为列表。

基本上,代替list - 直接使用list构造函数,您需要一个listcomp,在推进list之前将组迭代器转换为groupby s对象,替换:

group_list = list(itertools.groupby(nums, key=lambda x: x>=0))

使用:

group_list = [(k, list(g)) for k, g in itertools.groupby(nums, key=lambda x: x>=0)]

大多数itertools模块类型的设计旨在避免隐式存储数据,因为它们旨在与潜在的巨大输入一起使用。如果所有的石斑鱼都存储了输入中所有数据的副本(并且groupby对象必须确保追溯填充它们),它将变得丑陋,并且可能意外地记忆。通过强制您将值显式存储,根据Python的Zen,您不会无意中无意中存储无限量的数据:

  

明确比隐含更好。