修改嵌套字典中指定numpy数组元素时为何所有实例同步变更?
问题原因分析
嘿,你遇到的这个问题其实是Python里可变对象的引用赋值导致的新手常见坑!
当你在循环里写sim_trips[sim] = zero_trips时,并没有为每个sim创建独立的zero_trips副本——相反,你是让sim_trips里的所有键(Sim 1、Sim 2)都指向同一个字典对象,包括字典里的两个numpy数组,也是同一个数组对象的引用。所以当你修改其中一个引用指向的数组元素时,所有指向这个数组的地方都会同步变化。
解决方案
这里有几种简单的修复方法,选哪种都能解决你的问题:
方法1:使用深拷贝(最通用)
因为你的字典里包含numpy数组这种嵌套的可变对象,所以需要用copy.deepcopy()来完全复制整个结构,确保每个sim都有独立的字典和数组:
import copy import numpy as np simulations = {"Sim 1" : "Sim a", "Sim 2" : "Sim b"} zero_trips = {"Option_1" : np.zeros((2, 2)), "Option_2" : np.zeros((2, 2))} sim_trips = {} for sim in simulations: sim_trips[sim] = copy.deepcopy(zero_trips) # 深拷贝整个字典及内部数组 # 测试修改 sim_trips["Sim 1"]["Option_1"][0,0] += 1 print(sim_trips)
方法2:循环内重新创建对象
直接在每次循环里生成新的字典和数组,从根源上避免引用共享:
import numpy as np simulations = {"Sim 1" : "Sim a", "Sim 2" : "Sim b"} sim_trips = {} for sim in simulations: # 每次循环都生成全新的字典和numpy数组 sim_trips[sim] = {"Option_1" : np.zeros((2, 2)), "Option_2" : np.zeros((2, 2))} # 测试修改 sim_trips["Sim 1"]["Option_1"][0,0] += 1 print(sim_trips)
方法3:手动拷贝字典和数组
如果你不想用深拷贝,也可以手动拷贝字典,再对每个numpy数组单独拷贝:
import numpy as np simulations = {"Sim 1" : "Sim a", "Sim 2" : "Sim b"} zero_trips = {"Option_1" : np.zeros((2, 2)), "Option_2" : np.zeros((2, 2))} sim_trips = {} for sim in simulations: # 先拷贝字典(浅拷贝),再对每个数组做独立拷贝 new_trips = zero_trips.copy() new_trips["Option_1"] = new_trips["Option_1"].copy() new_trips["Option_2"] = new_trips["Option_2"].copy() sim_trips[sim] = new_trips # 测试修改 sim_trips["Sim 1"]["Option_1"][0,0] += 1 print(sim_trips)
验证效果
运行上面任意一种方法后,修改Sim 1的数组元素,只会影响Sim 1对应的条目,Sim 2的数组会保持初始的全零状态,完全符合你的期望输出。
内容的提问来源于stack exchange,提问作者aehruesch
相关产品推荐
相关产品推荐

