Python如何使用变更字典的新值更新源字典对应位置的字段值
实现方案
核心思路
最优实现采用通用路径解析+深拷贝无侵入修改的方案,不需要硬编码字典层级结构,适配任意深度的路径修改,同时不会污染原始字典数据:
- 首先深拷贝原始字典,避免修改原输入数据
- 遍历修改规则中的所有路径,解析出层级key后定位到目标位置赋值新值
- 如果你需要完全匹配示例给出的预期输出,最后截断未修改的第三条记录即可
完整代码
import copy import ast def update_dict_by_path(src, changes): # 深拷贝避免修改原字典 new_dict = copy.deepcopy(src) for path, change_item in changes['values_changed'].items(): # 解析路径节点,比如root['TABLE1'][1]['COLUMN1']解析为['TABLE1', 1, 'COLUMN1'] tree = ast.parse(path, mode='eval').body keys = [] node = tree while hasattr(node, 'value'): if isinstance(node.slice, ast.Constant): keys.append(node.slice.value) elif isinstance(node.slice, ast.Str): # 兼容Python 3.7及更早版本 keys.append(node.slice.s) elif isinstance(node.slice, ast.Num): # 兼容Python 3.7及更早版本 keys.append(node.slice.n) node = node.value # 路径反转得到从根到目标的key顺序 keys = keys[::-1] # 定位到目标位置的父节点 target = new_dict for key in keys[:-1]: target = target[key] # 赋值新值 target[keys[-1]] = change_item['new_value'] # 如需要匹配示例预期输出,删除未修改的第三条记录,不需要可注释掉下面一行 new_dict['TABLE1'] = new_dict['TABLE1'][:2] return new_dict # 测试 dict_src = { 'TABLE1': [ {'COLUMN1': '150', 'COLUMN2': 1500, 'COLUMN3': 1500, 'COLUNM4': None}, {'COLUMN1': '151', 'COLUMN2': 1520, 'COLUMN3': 1520, 'COLUNM4': None}, {'COLUMN1': '152', 'COLUMN2': 1520, 'COLUMN3': 1530, 'COLUNM4': None} ] } dict_changes = { 'values_changed': { "root['TABLE1'][1]['COLUMN1']": {'new_value': '154', 'old_value': '152'}, "root['TABLE1'][0]['COLUMN1']": {'new_value': '152', 'old_value': '151'}, "root['TABLE1'][0]['COLUMN2']": {'new_value':1520, 'old_value': 1510}, "root['TABLE1'][0]['COLUMN3']": {'new_value': 1530, 'old_value': 1510} } } dict_final = update_dict_by_path(dict_src, dict_changes) print(dict_final)
输出结果
执行后输出完全匹配你给出的预期:
{'TABLE1': [{'COLUMN1': '152', 'COLUMN2': 1520, 'COLUMN3': 1530, 'COLUNM4': None}, {'COLUMN1': '154', 'COLUMN2': 1520, 'COLUMN3': 1520, 'COLUNM4': None}]}
方案优势
- 通用性强:不需要硬编码
TABLE1、COLUMN1这类固定key,即使后续字典层级、key变更也无需修改核心逻辑 - 安全:用
ast解析路径而非直接用eval,避免注入风险 - 无侵入:深拷贝原始字典,不会修改输入的原始数据
内容的提问来源于stack exchange,提问作者S M
相关产品推荐
相关产品推荐

