itertools.groupby只对相邻相同元素分组,非SQL式全局聚合;必须先按key排序,否则相同键值分散会导致错误分组,且group_iterator只能遍历一次。

直接说结论:itertools.groupby 不会自动按值分组,它只对**相邻相同元素**分组;想按任意字段分组,必须先排序。
为什么 groupby 似乎“漏掉”了重复项?
这是最常踩的坑:groupby 不是 SQL 的 GROUP BY,它不扫描整个列表,只看当前连续块。比如对 [1,2,1] 调用 groupby,会得到三组:(1), (2), (1),而不是两组。
- 根本原因:它内部只比较相邻两个元素是否相等(或 key 函数返回值是否相等)
- 典型错误写法:
list(groupby([{'type':'a'}, {'type':'b'}, {'type':'a'}], key=lambda x: x['type']))→ 三个独立组 - 正确前提:输入必须按 key 排好序,例如用
sorted(data, key=lambda x: x['type'])预处理
如何按字典字段分组并保留原始结构?
常见需求:把 [{'name': 'Alice', 'dept': 'HR'}, {'name': 'Bob', 'dept': 'IT'}, ...] 按 dept 分组为字典,键是部门名,值是该部门人员列表。
- 必须两步走:先
sorted,再groupby -
groupby返回的是迭代器,每个元素是(key, group_iterator),需用list()转成列表 - 示例:
from itertools import groupby <p>data = [{'name': 'Alice', 'dept': 'HR'}, {'name': 'Bob', 'dept': 'IT'}, {'name': 'Charlie', 'dept': 'HR'}] sorted_data = sorted(data, key=lambda x: x['dept']) result = {k: list(g) for k, g in groupby(sorted_data, key=lambda x: x['dept'])}</p><h1>→ {'HR': [{'name': 'Alice', 'dept': 'HR'}, {'name': 'Charlie', 'dept': 'HR'}], 'IT': [{'name': 'Bob', 'dept': 'IT'}]}
和 pandas.groupby 或 defaultdict 比有什么区别?
选 groupby 的真实理由不是“更高级”,而是内存敏感场景下流式处理——它不把全部数据加载进内存,适合处理已排序的大文件行或生成器输出。
立即学习“Python免费学习笔记(深入)”;
-
pandas.groupby:自动全量分组,支持聚合函数,但需整块载入内存 -
defaultdict(list):简单、无需排序,适合小数据或实时插入,但逻辑要自己写 -
itertools.groupby:零内存额外开销,但强依赖输入顺序;一旦错序,结果不可逆 - 性能提示:排序本身是
O(n log n),如果原数据本就有序(如日志按时间戳写入),groupby就是真正的O(n)
最容易被忽略的一点:key 函数返回值必须可哈希且稳定。比如用 datetime 对象做 key 时,若存在微秒差异或时区混用,相邻项可能被拆成不同组——这不是 groupby 的 bug,是输入没对齐。


















