You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何itertools.groupby转为dict后,取值得到空列表?

为什么itertools.groupby转成dict后遍历分组会得到空列表?

核心原因:groupby返回的是绑定原序列的迭代器,而非持久化容器

itertools.groupby的工作逻辑是实时遍历原序列、按需生成分组,它返回的分组生成器(代码里的v_gen)并不是独立存储分组数据的容器,而是和原序列的迭代位置绑定的一次性迭代器。

当你执行dict(groupby(raw, key=lambda x: x["age"]))时,Python会完整迭代一遍groupby对象,把所有(key, 生成器)键值对存入字典。但这个过程中,原序列的迭代指针已经走到了末尾——每个分组生成器其实只是"指向"原序列中对应分组的位置,当原序列被遍历完后,这些生成器再被调用时就没有元素可以返回了,所以A部分执行list(grouped[v])会得到空列表。

而B部分直接遍历groupby对象时,每拿到一个分组生成器就立刻用list()消费它,这时候原序列的迭代指针还停留在对应分组的位置,所以能正常取出元素。

解决办法:构造字典时提前把分组元素转为列表

如果需要把分组结果持久化到字典里,要在生成字典的过程中就把每个分组的生成器转为列表(或其他容器),而不是直接存储生成器本身:

from itertools import groupby

raw = [
        {"name": "A", "age": 20},
        {"name": "A", "age": 20},    
        {"name": "A", "age": 21},
        {"name": "A", "age": 21},
    ]

# 提前将分组生成器转为列表存入字典
grouped = {key: list(gen) for key, gen in groupby(raw, key=lambda x: x["age"])}

for v in grouped:
    print(grouped[v])

执行这段代码后,输出就会符合你的期望:

[{'name': 'A', 'age': 20}, {'name': 'A', 'age': 20}]
[{'name': 'A', 'age': 21}, {'name': 'A', 'age': 21}]

额外注意:groupby要求原序列按分组key排序

groupby只会把连续相同key的元素归为一组,如果原序列没有按分组key排序,可能会得到不符合预期的分组结果。如果需要全局按key分组,记得先排序:

raw_sorted = sorted(raw, key=lambda x: x["age"])
grouped = {key: list(gen) for key, gen in groupby(raw_sorted, key=lambda x: x["age"])}

内容的提问来源于stack exchange,提问作者ShIRann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:37:34