循环中修改字典副本却意外改动原字典的技术求助
解决循环中修改字典副本导致原字典被改动的问题
这问题我之前也踩过坑!核心原因是Python字典的浅拷贝(shallow copy)特性——当你用普通的copy()方法或者dict()构造函数复制字典时,只会复制外层的键值对,但嵌套的字典(比如你database['asteroids']里的每个小行星对象)其实还是指向原内存中的对象引用。在循环里操作这些嵌套内容时,就会直接修改到原字典里的对应数据;而非循环场景下,可能你没碰嵌套层级,或者操作的是数字、字符串这类不可变类型,所以没触发这个问题。
具体解决方案:用深拷贝替代浅拷贝
要彻底复制包括嵌套结构在内的所有内容,需要使用copy模块里的deepcopy()方法,它会递归复制所有层级的对象,让副本和原字典完全独立。
结合你的数据示例,具体代码如下:
1. 错误的浅拷贝写法(会改动原字典)
database = { 'asteroids': { '20 6': {'capacity': 12, 'pos': [20, 6], 'farm_rate': 2}, '5 21': {'capacity': 12, 'pos': [5, 21], 'farm_rate': 2}, '10 14': {'capacity': 12, 'pos': [10, 14], 'farm_rate': 1} } } # 浅拷贝外层字典,嵌套对象还是引用原数据 asteroids_copy = database['asteroids'].copy() for asteroid_key in asteroids_copy: # 修改嵌套字典的capacity,会同步改动原database asteroids_copy[asteroid_key]['capacity'] -= 1 print(database['asteroids']['20 6']['capacity']) # 输出11,原字典被修改了!
2. 正确的深拷贝写法(原字典不受影响)
import copy database = { 'asteroids': { '20 6': {'capacity': 12, 'pos': [20, 6], 'farm_rate': 2}, '5 21': {'capacity': 12, 'pos': [5, 21], 'farm_rate': 2}, '10 14': {'capacity': 12, 'pos': [10, 14], 'farm_rate': 1} } } # 深拷贝所有层级的内容,副本完全独立于原字典 asteroids_copy = copy.deepcopy(database['asteroids']) for asteroid_key in asteroids_copy: asteroids_copy[asteroid_key]['capacity'] -= 1 print(database['asteroids']['20 6']['capacity']) # 输出12,原字典未被改动 print(asteroids_copy['20 6']['capacity']) # 输出11,副本正常修改
补充说明
如果你的非循环场景只是操作外层字典的键(比如添加/删除小行星键),浅拷贝就足够;但只要涉及修改嵌套的字典、列表这类可变对象,就必须用深拷贝来避免联动修改原数据。
内容的提问来源于stack exchange,提问作者Manoa
相关产品推荐
相关产品推荐

