list
函数在应用于嵌套生成器时的行为如何?在下面的代码片段中,我发现行为相当令人费解:似乎list
消耗了大多数嵌套生成器,而最后一个仍然保留了一个元素:
>>> from itertools import groupby
>>> xs = [1, 2, 2, 3, 3]
>>> for k, g in list(groupby(xs)):
... print(k, list(g))
1 []
2 []
3 [3]
答案 0 :(得分:6)
不,对list的调用不会消耗嵌套的迭代器/生成器。
此行为是itertools.groupby
所特有的,并在文档中进行了描述:
返回的组本身就是共享底层的迭代器 可与
groupby()
迭代。因为源是共享的,所以groupby()
对象已提前,上一组不再可见。
[强调我的]
如果您查看文档中提供的等效于itertools.groupby
的Python源代码,这将更加明确:
class groupby(object):
def __init__(self, iterable, key=None):
if key is None:
key = lambda x: x
self.keyfunc = key
self.it = iter(iterable) # shared iterator
self.tgtkey = self.currkey = self.currvalue = object()
def __iter__(self):
return self
def next(self):
while self.currkey == self.tgtkey:
self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue)
self.tgtkey = self.currkey
return (self.currkey, self._grouper(self.tgtkey))
def _grouper(self, tgtkey):
while self.currkey == tgtkey:
yield self.currvalue
self.currvalue = next(self.it) # Exit on StopIteration
self.currkey = self.keyfunc(self.currvalue)
结果中显示的最后一个[3]
是self.currvalue
(由_grouper
产生的),该groupby
已经从groupby
对象的上一次调用分配到了bluemix iam org-rename <old_org_name> <new_org_name>
bluemix iam org-delete <org_name>
。
为了保留每个组的结果,您应该将它们存储在一个列表中,并且不会同时消耗{{1}}个对象。