python - 将列表函数应用于 itertools.groupby 中的嵌套生成器

标签 python python-3.x iterator generator

当应用于嵌套生成器时,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]

最佳答案

不,对 list 的调用不会消耗嵌套的迭代器/生成器。

该行为是 itertools.groupby 特有的并在文档中进行了描述:

The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible.

[强调我的]

如果您查看文档中提供的与 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 对象上调用 next。

为了保留每个组的结果,您应该将它们存储在一个列表中,而不是一次性使用 groupby 对象。

关于python - 将列表函数应用于 itertools.groupby 中的嵌套生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41246209/

相关文章:

python - Unicode 列表到字符串列表 Python 2

python - Pandas DataFrame 基于条件进行分组

python - 在线程上调用时,Python函数无法开始执行

c++ - 检查值存在于 std::map - C++

c++ - C++的value_type可以从iterator_traits扩展到所有类型吗?

python - 使用 Panda read_csv 函数仅加载行列表 - Python

python - Feedparser-基础如何

c++ - 返回 Vector 的新实例

python - openpyxl 数据透视表和 pandas 数据透视表

python-3.x - 连接到 Django 默认失败