Cod*_*755 1 python grouping iterator python-itertools
我试图使用itertools.groupby帮助我按正或负属性对整数列表进行分组,例如:
输入
[1,2,3, -1,-2,-3, 1,2,3, -1,-2,-3]
Run Code Online (Sandbox Code Playgroud)
将返回
[[1,2,3],[-1,-2,-3],[1,2,3],[-1,-2,-3]]
Run Code Online (Sandbox Code Playgroud)
但是,如果我:
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]
[]
[]
Run Code Online (Sandbox Code Playgroud)
但是,如果我没有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]
Run Code Online (Sandbox Code Playgroud)
我不明白的是,groupby对象是由一对键和_grouper对象组成的迭代器,对list()groupby对象的调用不应该消耗该_grouper对象吗?
即使消耗掉了,我又如何[-3]从第二个元素中得到呢?
根据文档,明确指出,前进groupby对象会导致前一组不可用(实际上是空的):
返回的组本身就是一个与共享基础可迭代对象的迭代器
groupby()。因为源是共享的,所以当groupby()对象前进时,先前的组将不再可见。因此,如果以后需要该数据,则应将其存储为列表。
基本上,不是list直接使用list构造函数进行-ify操作,而是需要一个listcomp,它可以list在推进groupby对象之前从组迭代器转换为s ,替换为:
group_list = list(itertools.groupby(nums, key=lambda x: x>=0))
Run Code Online (Sandbox Code Playgroud)
与:
group_list = [(k, list(g)) for k, g in itertools.groupby(nums, key=lambda x: x>=0)]
Run Code Online (Sandbox Code Playgroud)
大多数itertools模块类型的设计旨在避免隐式存储数据,因为它们旨在与潜在的大量输入一起使用。如果所有石斑鱼都存储了来自输入的所有数据的副本(并且该groupby对象必须确保追溯填充它们),它将变得很丑陋,并有可能意外地破坏内存。通过强制您显式存储值,您不会意外地按照Python的Zen意外存储无限制的数据量:
显式胜于隐式。