documentation 对此做了说明:
返回的组本身就是一个迭代器,它共享底层
可使用 groupby() 进行迭代。因为源是共享的,当
groupby() 对象是高级的,以前的组不再可见。
因此,如果以后需要该数据,则应将其存储为列表:
groups = []
uniquekeys = []
data = sorted(data, key=keyfunc)
for k, g in groupby(data, keyfunc):
groups.append(list(g)) # Store group iterator as a list
uniquekeys.append(k)
在尝试遍历返回的组迭代器之前,您已经耗尽了 groupby 对象(通过将其转换为列表),因此除了最后一个组之外的所有组都将丢失。
通过查看函数的 Python 实现更容易找出原因:
class groupby(object):
# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
def __init__(self, iterable, key=None):
if key is None:
key = lambda x: x
self.keyfunc = key
self.it = iter(iterable)
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)
self.currkey = self.keyfunc(self.currvalue)
self.tgtkey = self.currkey
return (self.currkey, self._grouper(self.tgtkey))
def _grouper(self, tgtkey): # This is the "group" iterator
while self.currkey == tgtkey: # self.currkey != tgtkey if you advance groupby and then try to use this object.
yield self.currvalue
self.currvalue = next(self.it)
self.currkey = self.keyfunc(self.currvalue)
调用next(groupby) 将指向底层可迭代对象(self.currvalue) 的内部指针前进到下一个键,然后返回当前键(self.currkey) 和_grouper 迭代器。 _grouper 将当前键作为参数(称为tgtkey),并将产生值(并重新计算self.currkey),直到self.currkey 与tgtkey 不同,这意味着它返回了与当前密钥。因此,如果您在使用 _grouper 对象之前提前 groupby,self.currkey 将永远等于 tgtkey,因此 _grouper 迭代器将不会返回任何内容。
如果出于某种原因您确实需要将groupby 结果存储在列表中,您必须这样做:
gby_list = []
for key, vals in gby:
gby_list.append(key, list(vals))
或者:
gby_list = [key, list(vals) for key, vals in gby]