我正在编写一个动态创建字典的Python代码,将其初始化为引用字典,并修改字典中的特定值。但是,我发现不仅我得到了意想不到的结果,而且参考字典也被修改了。 我的代码:
tdict={'a':'1','b':'2','c':'3'}
newdict={}
for i in range(5):
newdict['name'+str(i)]=tdict
newdict['name'+str(i)]['a']='value'+str(i)
print 'tdict: ',tdict
print 'newdict: ',newdict
结果:
tdict: {'a': 'value0', 'c': '3', 'b': '2'}
tdict: {'a': 'value1', 'c': '3', 'b': '2'}
tdict: {'a': 'value2', 'c': '3', 'b': '2'}
tdict: {'a': 'value3', 'c': '3', 'b': '2'}
tdict: {'a': 'value4', 'c': '3', 'b': '2'}
newdict: {'name4': {'a': 'value4', 'c': '3', 'b': '2'}, 'name2': {'a': 'value4', 'c': '3', 'b': '2'}, 'name3': {'a': 'value4', 'c': '3', 'b': '2'}, 'name0': {'a': 'value4', 'c': '3', 'b': '2'}, 'name1': {'a': 'value4', 'c': '3', 'b': '2'}}
而我期待我的'新命'就像:
newdict: {'name4': {'a': 'value4', 'c': '3', 'b': '2'}, 'name2': {'a': 'value2', 'c': '3', 'b': '2'}, 'name3': {'a': 'value3', 'c': '3', 'b': '2'}, 'name0': {'a': 'value0', 'c': '3', 'b': '2'}, 'name1': {'a': 'value1', 'c': '3', 'b': '2'}}
任何人都可以帮我弄清楚为什么会这样吗?另外,为什么当我没有给它分配任何值时,参考字典'tdict'会被改变?
提前致谢
答案 0 :(得分:2)
您正在tdict
词典的每个值中存储newdict
的引用:
newdict['name'+str(i)]=tdict
然后您通过执行
修改'a'
的密钥tdict
# newdict['name'+str(i)] is a reference to tdict
newdict['name'+str(i)]['a']='value'+str(i)
# this is equivalent to doing
tdict['a']='value'+str(i)
您可能想要的是在新词典词典中存储tdict
的副本:
newdict['name'+str(i)]=dict(tdict)
使用现有字典作为构造函数参数创建新字典会创建一个浅表副本,您可以在其中为现有键分配新值。你不能(或你不想要的)是修改这个字典中的可变值。例如:
>>> a={'a': 1, 'b': 2, 'c': [1,2,3]}
>>> b=dict(a)
>>> b['a']=9
>>> a
{'a': 1, 'c': [1, 2, 3], 'b': 2}
>>> b
{'a': 9, 'c': [1, 2, 3], 'b': 2}
>>> b['c'].append(99)
>>> a
{'a': 1, 'c': [1, 2, 3, 99], 'b': 2}
>>> b
{'a': 9, 'c': [1, 2, 3, 99], 'b': 2}
如果要修改字典中的可变值,则需要创建深层副本:
>>> import copy
>>> a={'a': 1, 'b': 2, 'c': [1,2,3]}
>>> b=copy.deepcopy(a)
>>> b['a']=9
>>> b['c'].append(99)
>>> a
{'a': 1, 'c': [1, 2, 3], 'b': 2}
>>> b
{'a': 9, 'c': [1, 2, 3, 99], 'b': 2}
答案 1 :(得分:0)
只是因为你正在引用tdict而不是副本。要复制,您可以使用
newdict['name'+str(i)] = tdict.copy()
或
newdict['name'+str(i)] = dict(tdict)
希望有所帮助