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
相关产品推荐
相关产品推荐

