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

Python对比字典变更时key不存在如何避免KeyError并追加记录

Python双字典差异对比(新增键适配方案)

问题根因

原有代码直接通过old_data[child_key]取值,当键仅存在于新字典时,旧字典无对应键就会触发KeyError,同时原有嵌套循环逻辑冗余,多层遍历性能低且容易出现逻辑错误。

适配代码

场景1:单条字典对比(匹配你给出的示例结构)

import datetime

profile_data = {
     "degree":"Diploma in Mechanical Engineering",
     "id":"9b1a012837364cada8b15a1a84745dab",
     "location":"Melbourne-123",
     "major":"major-test",
     "start_date":"2011-01-01"
    }
changed_data = {
         "degree":"Diploma in Mechanical Engineering",
         "*field_of_study*":"fiel of stuy test-test",
         "id":"9b1a012837364cada8b15a1a84745dab",
         "location":"Melbourne-123",
         "major":"major-test",
         "start_date":"2011-01-01"
        }

result = []
# 先校验id一致
if profile_data['id'] == changed_data['id']:
    # 取两个字典所有键的并集,覆盖新增、删除、修改的所有字段场景
    all_keys = set(profile_data.keys()).union(set(changed_data.keys()))
    for key in all_keys:
        # 用get方法取值,键不存在时默认返回None,避免KeyError
        old_val = profile_data.get(key)
        new_val = changed_data.get(key)
        if old_val != new_val:
            result.append({
                'field': key,
                'current': old_val,
                'changed': new_val,
                'created_at': datetime.datetime.utcnow()
            })

场景2:多条字典列表对比(匹配你原有代码的循环逻辑结构)

import datetime

# 示例多条数据结构
profile_data_list = [
    {
        "degree":"Diploma in Mechanical Engineering",
        "id":"9b1a012837364cada8b15a1a84745dab",
        "location":"Melbourne-123",
        "major":"major-test",
        "start_date":"2011-01-01"
    }
]
changed_data_list = [
    {
        "degree":"Diploma in Mechanical Engineering",
        "*field_of_study*":"fiel of stuy test-test",
        "id":"9b1a012837364cada8b15a1a84745dab",
        "location":"Melbourne-123",
        "major":"major-test",
        "start_date":"2011-01-01"
    }
]

result = []
# 旧数据按id做映射,避免双层循环,提升匹配性能
old_data_map = {item['id']: item for item in profile_data_list}
for new_data in changed_data_list:
    new_id = new_data['id']
    # 可根据业务需求调整id不匹配时的逻辑,这里默认跳过
    if new_id not in old_data_map:
        continue
    old_data = old_data_map[new_id]
    all_keys = set(old_data.keys()).union(set(new_data.keys()))
    for key in all_keys:
        old_val = old_data.get(key)
        new_val = new_data.get(key)
        if old_val != new_val:
            result.append({
                'field': key,
                'current': old_val,
                'changed': new_val,
                'created_at': datetime.datetime.utcnow()
            })

方案说明

  • 用set().union()获取两个字典所有键的并集,新增字段、删除字段、修改字段的场景都可以覆盖
  • dict.get(key)默认返回None,也可以根据业务需要设置自定义默认值,比如dict.get(key, "")返回空字符串
  • 旧数据按id做映射的匹配方式,比原有双层循环遍历的时间复杂度更低,数据量大时性能优势更明显

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:15:03