Python嵌套字典多键引用同一子对象引发值同步修改异常问题
问题核心根源
Python 中字典属于可变引用类型,当执行symbolData = {'20MICRONS':{'CLOSEPRICE':0}}后,将该变量同时作为dateWiseStockData中20210318和20210319两个键的取值时,两个键的 value 指向的是内存中同一个嵌套字典实体,而非两份独立的字典副本。
无论通过哪个日期键修改对应子字典的CLOSEPRICE字段,本质都是修改这个公共字典实体的内容:
- 第一次循环遍历
20210318时,将公共字典的CLOSEPRICE赋值为17 - 第二次循环遍历
20210319时,将同一个公共字典的CLOSEPRICE重新赋值为18
最终两个日期键读取到的都是这个公共字典的最终值18,完全匹配实际运行的异常输出结果。
认知偏差校正
对嵌套字典的基础读写逻辑不存在本质理解错误,偏差核心是混淆了Python中可变类型的引用传递规则:
- 不可变类型(整数、字符串、元组)赋值时默认生成值拷贝,修改单个变量不会影响其他关联变量
- 可变类型(字典、列表、自定义类实例)赋值时默认传递内存地址引用,多个变量绑定到同一个内存实体,修改任意变量的内部属性,所有绑定该实体的引用都会同步感知到变化
很多人初次写Python时会默认“把同一个字典变量塞到其他结构的多个位置,会自动生成多份独立副本”,这个认知是错的,也是这类问题的最常见触发点。
修正方案
只要切断不同日期键之间的公共引用,为每个日期分配独立的字典实体,就能实现预期输出效果:
- 最直接的方式:为每个日期单独初始化独立的嵌套字典,不复用同一个
symbolData变量:
dateWiseStockData = { '20210318': {'20MICRONS': {'CLOSEPRICE': 0}}, '20210319': {'20MICRONS': {'CLOSEPRICE': 0}} }
- 如果需要复用相同的初始结构,必须使用深拷贝生成完全独立的副本,不能直接赋值引用:
import copy dateWiseStockData = { '20210318': copy.deepcopy(symbolData), '20210319': copy.deepcopy(symbolData) }
注意:仅使用浅拷贝copy.copy()无法解决问题,因为嵌套层级的子字典依然会绑定公共引用,修改时依然会出现互相覆盖的情况。
内容的提问来源于stack exchange,提问作者maverick9888
相关产品推荐
相关产品推荐

