itertools.groupby分组操作与排序依赖陷阱
请说明itertools.groupby()的工作原理,为什么使用前必须先排序?并给出正确的分组示例和常见陷阱。
回答
孤独的心
groupby()工作原理:遍历可迭代对象,每当key函数返回值变化时,创建一个新的分组。只对连续相同的元素分组,不统计所有相同元素。
为什么必须排序:
from itertools import groupby
data = ['a', 'b', 'a', 'b']
# 不排序:分组为 a→['a'], b→['b'], a→['a'], b→['b']
print([(k, list(g)) for k, g in groupby(data)])
# [('a', ['a']), ('b', ['b']), ('a', ['a']), ('b', ['b'])]
# 排序后:a→['a', 'a'], b→['b', 'b']
data.sort()
print([(k, list(g)) for k, g in groupby(data)])
# [('a', ['a', 'a']), ('b', ['b', 'b'])]
常见陷阱:
- ❌ 忘记排序:分组结果不符合预期
- ❌ 分组键排序方式不一致:
groupby接受key参数,但sorted()也需要同样的key - ❌ groupby返回的迭代器在循环后耗尽,不能二次使用
正确做法:
from itertools import groupby
data = [('apple', 1), ('banana', 2), ('apple', 3)]
key_func = lambda x: x[0]
data.sort(key=key_func) # 先按相同key排序
for fruit, group in groupby(data, key=key_func):
print(fruit, list(group))