You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pythonic方式按指定键连接两个字典列表?

按指定键合并两个字典列表的Pythonic方案

假设我们有两个字典列表 l1 和 l2:

l1 = [
    {"id": 0, "foo": 0},
    {"id": 1, "foo": 1},
    {"id": 2, "foo": 2},
    ...
]

l2 = [
    {"id": 0, "bar": 0},
    {"id": 1, "bar": 1},
    {"id": 2, "bar": 2},
    ...
]

我们需要按指定键(比如 "id")将两个列表合并,得到如下结果:

[
    {"id": 0, "foo": 0, "bar": 0},
    {"id": 1, "foo": 1, "bar": 1},
    {"id": 2, "foo": 2, "bar": 2},
    ...
]

现有方案的问题

你提到的两种方案各有不足:

  • 双重循环列表推导式:时间复杂度为 O(NM),数据量稍大时效率极低,且如果两个字典存在非指定键的重复键,后遍历的字典会覆盖前者的键值:
    [
        {**d1, **d2}
        for d1 in l1 for d2 in l2
        if d1["id"] == d2["id"]
    ]
    
  • 字典映射法:时间复杂度优化到了 O(N+M),但原写法略显繁琐,可读性可以进一步提升。

更优的解决方案

1. 简洁版字典映射法(推荐)

这个方法既保持了 O(N+M) 的高效性,又更简洁可读,还避免修改原列表的字典:

# 先将l1转换为id到字典副本的映射,避免修改原数据
merged_map = {d["id"]: d.copy() for d in l1}

# 遍历l2,将每个字典的内容更新到对应id的映射中
for d in l2:
    merged_map[d["id"]].update(d)

# 按l1的原始顺序输出结果
result = [merged_map[d["id"]] for d in l1]

2. 处理id不完整的场景

如果两个列表的id可能不重叠(比如有的id只在l1或l2中存在),可以用 collections.defaultdict 来统一处理:

from collections import defaultdict

merged_map = defaultdict(dict)
# 遍历两个列表的所有字典,按id合并
for d in l1 + l2:
    merged_map[d["id"]].update(d)

# 转换为列表,Python3.7+ 中普通dict会保留插入顺序
result = list(merged_map.values())

3. 有序列表快速合并(特定场景)

如果两个列表已经按id排序且id完全一一对应,可以用 zip 配合字典解包,效率同样是 O(N):

result = [{**d1, **d2} for d1, d2 in zip(l1, l2)]

注意:这个方法要求两个列表的id顺序完全匹配,否则会出现错误合并的情况。

方案对比

方案时间复杂度适用场景
双重循环列表推导式O(NM)数据量极小的测试场景
字典映射法O(N+M)大多数场景,推荐使用
zip快速合并O(N)列表已按id排序且一一对应
defaultdict法O(N+M)存在id不重叠的场景

内容的提问来源于stack exchange,提问作者Ci Leong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:20:23