基于键对列表元素分组:求含重复值的优雅实现方案
优雅实现:将键值对可迭代对象转为键对应值列表的字典
给定一个包含(key, value)对的可迭代对象,需要返回一个字典,其中每个键对应一个包含该键所有值(包括重复值)的列表。示例如下:
输入:
[ ('germany', 'john'), ('finland', 'olavi'), ('france', 'alice'), ('germany', 'gerd'), ('germany', 'john') ]
输出:
{ 'germany': ['john', 'gerd', 'john'], 'finland': ['olavi'], 'france': ['alice'] }
方案1:使用collections.defaultdict(最简洁常用)
这是Python处理这类分组问题的标准方案,defaultdict会自动为不存在的键创建列表类型的默认值,遍历过程中直接追加值即可:
from collections import defaultdict def group_pairs(pairs): result = defaultdict(list) for key, value in pairs: result[key].append(value) return dict(result) # 可选转为普通字典,不需要的话直接返回defaultdict即可
方案2:使用普通字典的setdefault方法
如果不想引入额外模块,原生字典的setdefault方法就能搞定——它会在键不存在时设置默认值并返回该值,存在时直接返回对应值,省去了判断键是否存在的步骤:
def group_pairs(pairs): result = {} for key, value in pairs: result.setdefault(key, []).append(value) return result
方案3:Python 3.10+ 字典合并运算符写法(另类简洁版)
如果追求极简语法,可结合字典合并运算符实现,但这种方式每次都会新建字典,性能不如前两种,仅适合小数据量场景:
def group_pairs(pairs): result = {} for key, value in pairs: result = result | {key: result.get(key, []) + [value]} return result
方案4:使用itertools.groupby(需注意排序)
itertools.groupby也能实现分组,但它仅对连续相同的键进行分组,所以必须先对输入按键排序。如果不需要保留原输入的键顺序,这个方案也可行:
from itertools import groupby from operator import itemgetter def group_pairs(pairs): sorted_pairs = sorted(pairs, key=itemgetter(0)) return {key: [v for k, v in group] for key, group in groupby(sorted_pairs, key=itemgetter(0))}
注意:该方法会改变键的顺序为排序后的顺序,而前两种方案在Python 3.7+中会保留键的首次插入顺序。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

