Python groupby函数无法识别相同键进行分组的问题排查
Python groupby分组重复键问题解析
问题场景
现有嵌套列表:
a = [['2.25.151989603747108360484758994222924880510', 1], ['2.25.23907329898781253437777953862543062317', 1], ['2.25.151989603747108360484758994222924880510', 2], ['2.25.23907329898781253437777953862543062317', 1], ['2.25.159215431212584126451402597802236328925', 1], ['2.25.339018106044083012102817776589396922392', 1], ['2.25.159215431212584126451402597802236328925', 1], ['2.25.23907329898781253437777953862543062317', 1], ['2.25.151989603747108360484758994222924880510', 1], ['2.25.159215431212584126451402597802236328925', 1], ['2.25.151989603747108360484758994222924880510', 1], ['2.25.339018106044083012102817776589396922392', 1], ['2.25.159215431212584126451402597802236328925', 1], ['2.25.151989603747108360484758994222924880510', 1], ['2.25.159215431212584126451402597802236328925', 1], ['2.25.339018106044083012102817776589396922392', 1], ['2.25.159215431212584126451402597802236328925', 1]]
尝试用groupby按子列表第一个元素分组,执行测试代码:
from itertools import groupby for key, group in groupby(a, lambda x: str(x[0]).strip()): print(key)
输出的键出现重复:
2.25.151989603747108360484758994222924880510 2.25.23907329898781253437777953862543062317 2.25.151989603747108360484758994222924880510 2.25.23907329898781253437777953862543062317 2.25.159215431212584126451402597802236328925 2.25.339018106044083012102817776589396922392 2.25.159215431212584126451402597802236328925 2.25.23907329898781253437777953862543062317 2.25.151989603747108360484758994222924880510 2.25.159215431212584126451402597802236328925 2.25.151989603747108360484758994222924880510 2.25.339018106044083012102817776589396922392 2.25.159215431212584126451402597802236328925 2.25.151989603747108360484758994222924880510 2.25.159215431212584126451402597802236328925
但通过以下代码验证,集合显示只有5个唯一键:
r=[] for m in a: for n in a: if m[0]==n[0]: r.append(m[0]) print(set(r))
输出:
{'2.25.105201430514553352325644071061576888668', '2.25.151989603747108360484758994222924880510', '2.25.159215431212584126451402597802236328925', '2.25.23907329898781253437777953862543062317', '2.25.339018106044083012102817776589396922392'}
问题原因
itertools.groupby的核心特性是仅对连续的相同键进行分组,它不会自动遍历整个列表去聚合所有分散的相同键元素。你的原始列表中,相同键的元素并非连续排列,而是被其他键的元素穿插分隔,因此groupby会将每一段连续的相同键视为独立分组,导致输出重复的键。
而set(r)能得到5个唯一键,是因为集合会对所有元素进行全局去重,完全忽略元素在列表中的位置顺序,两者的处理逻辑本质不同。
解决方案
方法1:先排序再分组
将列表按分组键排序后,相同键会连续排列,此时groupby就能正确聚合所有相同键的元素:
from itertools import groupby # 按子列表第一个元素排序 a_sorted = sorted(a, key=lambda x: x[0]) for key, group in groupby(a_sorted, lambda x: str(x[0]).strip()): print(key)
执行后会输出5个唯一键,每个仅出现一次。
方法2:用字典手动聚合(无需排序)
如果不需要改变原列表的顺序,或者不想排序,可以用字典直接收集所有相同键的元素:
group_dict = {} for item in a: key = str(item[0]).strip() # 若键不存在则初始化列表,否则追加元素 group_dict.setdefault(key, []).append(item) # 遍历字典查看分组结果 for key in group_dict: print(key)
内容的提问来源于stack exchange,提问作者GhostRider
相关产品推荐
相关产品推荐

