Python修改外层字典子项时为何所有子字典值同步更新?
核心原因
这是Python可变对象的引用共享机制导致的,不存在子字典各自独立的情况:
- 你在遍历
nameList的外层循环之前,只在内存中创建了唯一1个zeroItemDict对象 - 循环执行
nameDict[n] = zeroItemDict时,并没有生成新的子字典实例,只是把这同一个字典的内存引用,依次绑定到了'Alice'、'Bob'、'Charlie'三个外层键上 - 三个外层键指向的是完全相同的内存地址,修改任意一个键对应的子字典内容,本质上就是修改这份唯一的子字典对象,因此所有键读取到的内容都会同步变化。
可以通过简单代码验证上述逻辑:在原代码赋值循环执行完后,执行print(id(nameDict["Alice"]) == id(nameDict["Bob"]) == id(nameDict["Charlie"])),会输出True,直接证明三者指向同一个对象。
正确实现方式
要让每个外层键对应独立的子字典对象,只需要在给nameDict赋值时,每次生成新的字典实例即可:
- 写法1:遍历人名时,逐个创建新的子字典并填充零值
for n in nameList: new_item_dict = {} for i in itemList: new_item_dict[i] = 0 nameDict[n] = new_item_dict
- 写法2:用字典推导式简化生成逻辑,代码更简洁
for n in nameList: nameDict[n] = {i: 0 for i in itemList}
- 写法3:保留外层统一的
zeroItemDict模板,每次赋值时对其做浅拷贝(当前场景所有值都是不可变整数,浅拷贝足够用)
for n in nameList: nameDict[n] = zeroItemDict.copy()
注意:如果子字典内包含嵌套的可变对象(比如列表、其他子字典),需要用
copy.deepcopy(zeroItemDict)完成拷贝,否则嵌套的可变值依然会发生引用共享的问题。
内容的提问来源于stack exchange,提问作者jsowers
相关产品推荐
相关产品推荐

