Python嵌套字典更新问题:update方法失效原因及非递归解决方案
为什么字典update方法会替换嵌套字典,而非合并?如何实现浅层次的嵌套更新?
咱们先搞懂为什么update会让你觉得“失效”——其实它完全符合Python的设计逻辑:dict.update()只会直接替换顶层键对应的值,不会递归处理嵌套的字典结构。
你看你的例子,new_dict里的'account'是一个全新的字典,当你调用old_dict.update(new_dict)时,Python会直接把old_dict里的'account'键对应的值,换成new_dict里的这个新字典。原来account下的displayName、domain这些字段自然就被覆盖没了——因为整个嵌套字典都被换掉了,而不是合并里面的键值对。
不用递归的简单实现方案
既然你不想用递归,那咱们写一个浅层次的嵌套更新函数就足够处理你的场景了——只针对顶层的嵌套字典做合并,其他非字典值直接替换:
def shallow_nested_update(old_dict, new_dict): for key, new_val in new_dict.items(): # 如果新值是字典,且老字典里对应键也是字典,就合并而非替换 if isinstance(new_val, dict) and key in old_dict and isinstance(old_dict[key], dict): old_dict[key].update(new_val) else: # 非字典类型直接替换 old_dict[key] = new_val
用你的测试代码跑一下试试:
old_dict = {'account': {'user': None, 'displayName': None, 'domain': '', 'dnsSrv': False, 'proxies': [{'addr': None, 'port': 5060}], 'vendor': 2, 'auth': {'user': None, 'passwd': None}, 'transport': 2, 'regInterval': 3600, 'avpfInterval': 3, 'sipsUri': False, 'avpf': False, 'reqRegister': True, 'pubPresenceInfo': False}} new_dict = {'account': {'user': '007', 'dnsSrv': True, 'proxies': [{'addr': '10.10.10.201'}], 'pubPresenceInfo': False}} shallow_nested_update(old_dict, new_dict) print("updated data") print(old_dict)
运行后你会发现,old_dict里的account字典保留了原来的displayName、domain、auth等所有字段,只更新了new_dict里指定的user、dnsSrv、proxies和pubPresenceInfo。
补充说明
这里要注意:对于proxies这种列表类型,这个函数还是会直接替换(因为列表不是字典)。如果你的场景需要部分更新列表里的元素,那得单独加逻辑处理,但从你的需求来看,这个浅层次的方案已经能解决核心问题了。
内容的提问来源于stack exchange,提问作者ankur katiyar
相关产品推荐
相关产品推荐

