我在python中创建了一个字典。
dict1 = {}
dict2 = {'a': 0,
'b': 0,
'c': 0}
for i in range(1, 4):
dict1.update({i : dict2})
print(dict1)
output: {1: {'a': 0, 'c': 0, 'b': 0},
2: {'a': 0, 'c': 0, 'b': 0},
3: {'a': 0, 'c': 0, 'b': 0}}
我现在想在第一个字典中更改'a'的值。
dict1[1]['a'] += 1
输出看起来像这样。
print(dict1)
output: {1: {'a': 1, 'c': 0, 'b': 0},
2: {'a': 1, 'c': 0, 'b': 0},
3: {'a': 1, 'c': 0, 'b': 0}}
所有“ a”值都发生了变化,而不仅仅是第一个字典中的一个。这是为什么?以及如何只更改第一个字典中的值?
答案 0 :(得分:3)
您在所有新的dict条目中引用相同的dict(dict2)。在更新dict2
中的值时,只需复制dict1
:
>>> dict1 = {}
>>> dict2 = {'a': 0,
... 'b': 0,
... 'c': 0}
>>> dict1.update({i:dict2.copy() for i in range(1,4)})
>>> dict1
{1: {'a': 0, 'b': 0, 'c': 0}, 2: {'a': 0, 'b': 0, 'c': 0}, 3: {'a': 0, 'b': 0, 'c': 0}}
>>> dict1[1]["a"] = 1
>>> dict1
{1: {'a': 1, 'b': 0, 'c': 0}, 2: {'a': 0, 'b': 0, 'c': 0}, 3: {'a': 0, 'b': 0, 'c': 0}}
答案 1 :(得分:2)
在您的代码中,您将在所有位置更新同一词典的引用。由于所有这些引用都指向同一个对象,因此在修改一个对象时,它会在所有地方反映出来。
您需要深拷贝而不是浅拷贝,即不是在所有地方都引用同一本词典。
尝试以下代码:
import copy
dict1 = {}
dict2 = {'a': 0,
'b': 0,
'c': 0}
for i in range(1, 4):
dict1.update({i : copy.deepcopy(dict2)})
编辑:
正如@Netwave和@ gireesh4manu正确指出的,我在这里添加一个更新。
对于此特定问题的示例,不需要copy.deepcopy,因为字典中的内容都是不可变的。在这种情况下,下面的答案就足够了。
dict1 = {}
dict2 = {'a': 0,
'b': 0,
'c': 0}
for i in range(1, 4):
dict1.update({i : dict2.copy()})
但是,如果dict2
包含一些可变对象,则需要copy.deepcopy
。 dict2
的此类示例如下:
dict2: {'a': [1,2,3],
'b': [4,5,6],
'c':[]
}
在这种情况下,由于dict2
包含列表,因此对这些列表的任何更改都会在通过引用链接的任何地方反映出来。为避免这种情况,将需要copy.deepcopy
。
答案 2 :(得分:1)
字典是mutable objects,这意味着dict2
的所有值都指向内存中的同一对象。
在每次迭代中强制实例化新dict对象的一种方法是使用dict()函数:
for i in range(1, 4):
dict1.update({i : dict(dict2)})