Python itertools.groupby多键分组字典列表预排序后仍不生效
问题产生原因
核心问题出在sorted()方法的使用逻辑上:
sorted()是非原地排序函数,调用后会生成一个排好序的新列表返回,不会修改传入的原始列表。- 你写的第一行代码仅调用了
sorted(a,key=lambda x: (x['user_id'],x['clean_label'])),没有将返回的排序后列表赋值回变量a,后续执行itertools.groupby时,实际遍历的还是顺序未调整的原始列表:[111、112、111]。 itertools.groupby的分组逻辑是仅将连续相邻的同key元素归为同一组,非连续的同key元素会被拆分为独立分组,最终就输出了你看到的错误结果。
你单独验证排序时看到顺序符合预期,是因为验证环节你要么直接打印了sorted()的返回值,要么手动将排序结果赋值给了a,和实际执行分组的代码逻辑不一致。
修正方法
只需要将sorted()返回的排序结果赋值回原变量,保证传入groupby的列表已经按分组key排好序即可,修正后的完整代码如下:
import itertools a = [ {'user_id':'111','clean_label':'VIR SEPA'}, {'user_id':'112','clean_label':'VIR SEPA'}, {'user_id':'111','clean_label':'VIR SEPA'}, ] # 把排序后的新列表赋值回a a = sorted(a, key=lambda x: (x['user_id'], x['clean_label'])) # 执行分组 result = [ [item for item in group] for key, group in itertools.groupby(a, key=lambda x: (x['user_id'], x['clean_label'])) ]
执行后得到的result就是你期望的嵌套列表结构:
[ [{'user_id': '111', 'clean_label': 'VIR SEPA'}, {'user_id': '111', 'clean_label': 'VIR SEPA'}], [{'user_id': '112', 'clean_label': 'VIR SEPA'}] ]
内容的提问来源于stack exchange,提问作者Quxntin
相关产品推荐
相关产品推荐

