Python合并同键两字典 拼接列表值且不修改源字典的方法
问题场景
现有如下两个字典:
a = {'blocked': [29.686], 'dns': [-1], 'connect': [-1], 'send': [0.09], 'wait': [36.912], 'receive': [0.24], 'ssl': [-1], '_queued': [4.029]} b = {'blocked': [0], 'dns': [0], 'connect': [28.219], 'send': [0.126], 'wait': [33.053], 'receive': [0.279], 'ssl': [28.219], '_queued': [1.312]}
期望生成结果字典c,每个键对应的列表值由a、b同键的列表值拼接得到,预期结果如下:
c = {'blocked': [29.686, 0], 'dns': [-1, 0], 'connect': [-1, 28.219], 'send': [0.09, 0.126], 'wait': [36.912, 33.053], 'receive': [0.24, 0.279], 'ssl': [-1, 28.219], '_queued': [4.029, 1.312]}
之前尝试的两种字典推导式写法均存在问题:
# 写法1 c = {k: v.append(*b[k]) for k, v in a.items()} # 写法2 c = {k: v.extend(b[k]) for k, v in a.items()}
问题根源:
list.append()和list.extend()都是原地修改列表的方法,返回值为None,因此生成的字典所有值都是None- 两种写法直接操作字典a中存储的原列表对象,会意外修改原字典a的内容
另外提到的中转写法c = a本质只是给原字典a绑定了新的变量名,没有真正复制对象,执行扩展操作时依然会修改原字典a的内容。
简洁实现方案
直接用列表+运算符在字典推导式中完成拼接即可,+会生成全新的列表对象,既不会修改原字典a的内容,也不需要额外中转变量,一行代码即可实现需求:
c = {k: v + b[k] for k, v in a.items()}
方案说明
- 列表
+操作会返回两个列表拼接后的新列表,不会对参与拼接的原列表做任何修改,完全避免了原字典a被篡改的问题 - 写法和之前错误的推导式结构一致,逻辑直观,没有多余的临时变量或复制操作
如果遇到两个字典键不完全对齐的场景,可以基于两个字典键的并集做遍历,给缺失键设置空列表默认值即可:
c = {k: a.get(k, []) + b.get(k, []) for k in a.keys() | b.keys()}
内容的提问来源于stack exchange,提问作者Dennis Grasso
相关产品推荐
相关产品推荐

