Python UserDict修改嵌套字典未同步到上层容器问题咨询
问题原因
你遇到的差异本质是对象引用的问题,和UserDict本身的逻辑无关:
- 原生dict的示例中,
addr_1直接指向person_dict['addresses'][0]这个原生字典对象本身,你修改addr_1就是修改原对象,所以改动会同步到person_dict里。 - UserDict的示例中,你执行
user_addr_1 = UserDict(user_addresses[0])时,是基于原嵌套字典的数据拷贝创建了一个全新的UserDict实例,这个新实例和person_user_dict['addresses'][0]里存的原生字典没有任何引用关联。你修改的是这个独立的新UserDict对象,自然不会影响原来的person_user_dict。
解决方法
如果要让UserDict的行为和原生dict一致,可以选以下两种方案:
方案1:直接修改原嵌套对象,不新建UserDict实例
如果你不需要把嵌套字典也转成UserDict,直接修改原位置的对象即可:
# 直接修改原字典,改动会同步到person_user_dict person_user_dict['addresses'][0]['street'] = "123 The Road"
方案2:递归转换所有嵌套字典为UserDict
如果你需要整个结构所有层级的字典都是UserDict类型,可以写递归转换函数,初始化的时候就把所有嵌套层都转成UserDict:
def to_user_dict(obj): if isinstance(obj, dict): return UserDict({k: to_user_dict(v) for k, v in obj.items()}) elif isinstance(obj, list): return [to_user_dict(item) for item in obj] else: return obj # 初始化的时候递归转换所有层级 person_user_dict = to_user_dict(json.loads(person_string)) # 此时取到的user_addr_1就是结构里的UserDict实例引用,修改会同步到原结构 user_addr_1 = person_user_dict['addresses'][0] user_addr_1['street'] = "123 The Road"
这时候修改user_addr_1就会和原生dict的行为完全一致,改动会同步到整个person_user_dict结构里。
内容的提问来源于stack exchange,提问作者Paul W
相关产品推荐
相关产品推荐

