如何将仅支持3层字典键的change_value函数改写为循环实现?
问题
现有两个字典old_dict和new_dict,下述代码通过解析new_dict的键结构,从old_dict中获取对应值并更新new_dict。但其中的change_value函数仅支持最多3层字典键的操作,如何将该函数改写为循环实现,以支持任意层级的字典键?
附原代码:
old_dict = {'key1': {'password1': 'password', 'sensitive_data': {'MY_PASSWORD': 'old_passwrd'}}, 'key2': 'next_password', 'useless_key': 'useless_pass'} new_dict = {'key1': {'password1': 'password', 'sensitive_data': {'MY_PASSWORD': 'default_password'}}, 'key2': 'next_password'} def find_old(val_dict, value_list): for i in value_list: val_dict = val_dict[i] return val_dict def change_value(val_dict, value_list, value): if len(value_list) == 1: val_dict[value_list[0]] = value elif len(value_list) == 2: val_dict[value_list[0]][value_list[1]] = value elif len(value_list) == 3: val_dict[value_list[0]][value_list[1]][value_list[2]] = value def parser(parse_dict, value_list=None, level=0): if value_list is None: value_list = [] for i in parse_dict: value_list = value_list[:level] value_list.append(i) next_val = parse_dict[i] if type(next_val) is dict: parser(next_val, value_list, level=level + 1) else: old_value = (find_old(old_dict, value_list)) change_value(new_dict, value_list, old_value) parser(parse_dict=new_dict) print(new_dict) # 输出: {'key1': {'password1': 'password', 'sensitive_data': {'MY_PASSWORD': 'old_passwrd'}}, 'key2': 'next_password'}
解决方案
只需要修改change_value函数,通过循环逐层定位到目标字典的父级节点,最后给对应键赋值即可,这样就能支持任意层级的字典键操作:
def change_value(val_dict, value_list, value): # 循环遍历除最后一个键之外的所有键,定位到目标键的父字典 current_dict = val_dict for key in value_list[:-1]: current_dict = current_dict[key] # 给最后一个键赋值 current_dict[value_list[-1]] = value
完整代码验证
把修改后的change_value函数替换原函数,执行代码后依然能得到预期结果,同时现在可以支持任意层级的嵌套字典:
old_dict = {'key1': {'password1': 'password', 'sensitive_data': {'MY_PASSWORD': 'old_passwrd'}}, 'key2': 'next_password', 'useless_key': 'useless_pass'} new_dict = {'key1': {'password1': 'password', 'sensitive_data': {'MY_PASSWORD': 'default_password'}}, 'key2': 'next_password'} def find_old(val_dict, value_list): for i in value_list: val_dict = val_dict[i] return val_dict def change_value(val_dict, value_list, value): current_dict = val_dict for key in value_list[:-1]: current_dict = current_dict[key] current_dict[value_list[-1]] = value def parser(parse_dict, value_list=None, level=0): if value_list is None: value_list = [] for i in parse_dict: value_list = value_list[:level] value_list.append(i) next_val = parse_dict[i] if type(next_val) is dict: parser(next_val, value_list, level=level + 1) else: old_value = (find_old(old_dict, value_list)) change_value(new_dict, value_list, old_value) parser(parse_dict=new_dict) print(new_dict)
输出结果:
{'key1': {'password1': 'password', 'sensitive_data': {'MY_PASSWORD': 'old_passwrd'}}, 'key2': 'next_password'}
原理说明
- 循环遍历
value_list中除最后一个元素外的所有键,逐步深入嵌套字典,最终到达目标键所在的父级字典。 - 最后一步直接给父级字典的目标键赋值,这种写法不限制嵌套层级,无论多少层都能正常工作。
内容的提问来源于stack exchange,提问作者Alex Die
相关产品推荐
相关产品推荐

