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

Python:如何按'id'与'size'对比并合并不同字典列表?

字典列表按指定键合并优化方案

我有两个字典列表(lod),需要按id和size键判断是否为相似项:

  • 若相似,合并两个列表中的对应字典
  • 若不相似,为第一个列表中的对应字典添加count键并设默认值0

示例输入

lod1 = [{'id':1, 'size':1, 'colour':'a'}, {'id':1, 'size':2, 'colour':'ab'}, {'id':2, 'size':1, 'colour':'ab'}, {'id':2, 'size':2, 'colour':'ab'}]
lod2 = [{'id':1, 'size':1, 'count':1}, {'id':1, 'size':2, 'count':2}, {'id':2, 'size':1, 'count':3}]

期望输出

merged = [{'id':1, 'size':1, 'colour':'a', 'count': 1}, {'id':1, 'size':2, 'colour':'ab', 'count': 2},  {'id':2, 'size':1, 'colour':'ab', 'count':3}, {'id':2, 'size':2, 'colour':'ab', 'count': 0}]

现有实现

我自己写了一个实现,但代码繁琐不够优雅。我用过defaultdict,也了解DeepDiff库,但不知道怎么在这个场景里应用。我的代码如下:

def merge(l1, l2):
    lod1_pairs = [(i['id'], i['size']) for i in l1]
    lod2_pairs = [(i['id'], i['size']) for i in l2]
    mismatched = [pair for pair in lod1_pairs if pair not in lod2_pairs] 
    # 获取lod1中独有的键值对,为'count'设置默认值
    merged = []
    for i in lod1:
        if (i['id'], i['size']) in mismatched:
            # 为不匹配项添加'count'默认值
            temp_dict = i| {'count': 0} 
            merged.append(temp_dict)
        else:
            for j in lod2:
                    # 直接对比键值
                    if i['id'] == j['id'] and i['size'] == j['size']:
                        temp_dict = i | j # 合并字典
                        merged.append(temp_dict)
    return merged


lod1 = [{'id':1, 'size':1, 'colour':'a'}, {'id':1 , 'size':2, 'colour':'ab'}, {'id':2, 'size':1, 'colour':'ab'}, {'id':2, 'size':2, 'colour':'ab'}]
lod2 = [{'id':1, 'size':1, 'count':1}, {'id':1, 'size':2, 'count':2}, {'id':2, 'size':1, 'count':3}]
merged = merge(lod1,lod2)

优化方案

核心思路

你的代码嵌套循环会导致时间复杂度达到O(n*m),可以先把lod2转换成以(id, size)为键的字典,将查找操作降为O(1),整体复杂度优化到O(n+m),代码也更简洁。这个场景不需要用到DeepDiff,普通字典就能搞定。

优化后的代码

def merge_lod(lod1, lod2):
    # 将lod2转换为(id, size)为键的映射字典,快速查找匹配项
    lod2_map = {(item['id'], item['size']): item for item in lod2}
    merged = []
    for item in lod1:
        key = (item['id'], item['size'])
        # 获取匹配项,无匹配时用默认的{'count':0},合并字典
        merged_item = {**item, **lod2_map.get(key, {'count': 0})}
        merged.append(merged_item)
    return merged

# 测试
lod1 = [{'id':1, 'size':1, 'colour':'a'}, {'id':1, 'size':2, 'colour':'ab'}, {'id':2, 'size':1, 'colour':'ab'}, {'id':2, 'size':2, 'colour':'ab'}]
lod2 = [{'id':1, 'size':1, 'count':1}, {'id':1, 'size':2, 'count':2}, {'id':2, 'size':1, 'count':3}]
merged = merge_lod(lod1, lod2)
print(merged)

代码说明

  1. 构建映射字典:lod2_map把lod2中的每个字典用(id, size)作为唯一标识存储,后续查找对应项无需循环遍历。
  2. 合并逻辑:遍历lod1的每个字典,用lod2_map.get(key, {'count':0})获取匹配项,无匹配时返回默认值,再通过字典解包{**item, **...}合并两个字典(lod2仅含count键,不会和lod1的键冲突)。
  3. 顺序保持:结果列表的顺序和lod1完全一致,符合需求。

至于defaultdict,它更适合批量设置默认值的场景,这里用普通字典的get方法已经足够简洁,无需额外引入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:16:02