如何用DeepDiff比较字典列表并原地修改(或生成新字典列表)
利用DeepDiff结果更新字典列表
问题场景
有两个包含字典的列表dict_1和dict_2,通过deepdiff库的DeepDiff工具对比后得到值变更结果,需要将dict_1中对应的值用dict_2的修改值原地覆盖,或者生成新的字典列表dict_3。
原测试代码及执行结果:
import deepdiff dict_1 = [{"id": "first", "name": "first"}, {"id": "second", "name": "second"}, {"id": "third", "name": "third"}] dict_2 = [{"id": "first", "name": "first"}, {"id": "second modified", "name": "second modified"}, {"id": "third", "name": "third"}] diff = deepdiff.DeepDiff(dict_1, dict_2).get('values_changed',{}) print(diff)
执行输出:
{"root[1]['id']": {'new_value': 'second modified', 'old_value': 'second'}, "root[1]['name']": {'new_value': 'second modified', 'old_value': 'second'}}
期望得到的更新后结果:
dict_1 = [{"id": "first", "name": "first"}, {"id": "second modified", "name": "second modified"}, {"id": "third", "name": "third"}]
解决方案
1. 原地覆盖更新dict_1
通过解析DeepDiff返回的路径字符串,定位到dict_1中的目标元素,直接修改对应值:
import deepdiff dict_1 = [{"id": "first", "name": "first"}, {"id": "second", "name": "second"}, {"id": "third", "name": "third"}] dict_2 = [{"id": "first", "name": "first"}, {"id": "second modified", "name": "second modified"}, {"id": "third", "name": "third"}] diff = deepdiff.DeepDiff(dict_1, dict_2).get('values_changed', {}) # 遍历变更项,原地更新dict_1 for path, change_info in diff.items(): # 解析路径:提取列表索引和字典键 path_content = path.replace("root", "").strip() # 获取列表索引(如root[1]中的1) list_index = int(path_content.split('[')[1].split(']')[0]) # 获取字典键(如['id']中的id) dict_key = path_content.split("['")[1].split("']")[0] # 覆盖原数值 dict_1[list_index][dict_key] = change_info['new_value'] print(dict_1)
2. 生成新字典列表dict_3(不修改原数据)
如果不想改动原dict_1,可以先深拷贝原列表,再在拷贝后的新列表上修改:
import copy import deepdiff dict_1 = [{"id": "first", "name": "first"}, {"id": "second", "name": "second"}, {"id": "third", "name": "third"}] dict_2 = [{"id": "first", "name": "first"}, {"id": "second modified", "name": "second modified"}, {"id": "third", "name": "third"}] diff = deepdiff.DeepDiff(dict_1, dict_2).get('values_changed', {}) # 深拷贝生成新列表,避免修改原数据 dict_3 = copy.deepcopy(dict_1) for path, change_info in diff.items(): path_content = path.replace("root", "").strip() list_index = int(path_content.split('[')[1].split(']')[0]) dict_key = path_content.split("['")[1].split("']")[0] dict_3[list_index][dict_key] = change_info['new_value'] print("原dict_1:", dict_1) print("更新后的dict_3:", dict_3)
内容的提问来源于stack exchange,提问作者saromba
相关产品推荐
相关产品推荐

