我希望通过一些启示来覆盖我的挫败感 - 这里是用于演示问题的脚本的最小版本:
首先我创建一个字典:
dic = {
'foo':{},
'bar':{}
}
然后我们实例化一个可以迭代追加的模板字典
到dic
的键:
appendic= {
'is':'', # '' is a terminal value to be replaced later
}
所以我们在这里appendic
向dic
中的每个键添加dic['foo'] = appendic
dic['bar'] = appendic
:
dic['foo']['is'] = 'foo'
dic['bar']['is'] = 'bar'
现在我们用有意义的东西替换终端值''
print(dic['foo']['is'])
此时,我的直觉告诉我,如果我们打电话:
'foo'
我们得到'bar'
但是,Python会将{{1}} ...返回给我没有训练的头脑,这是违反直觉的。
问题:
答案 0 :(得分:9)
当您将appendic
分配给两个不同的密钥时,Python不会复制。它改为指定参考。
因此,dic['please_make_me_Foo']
和dic['dont_make_him_Bar']
都会引用同一个对象。这些不是单独的词典,它们都是同一个对象,一个appendic
也引用。
如果您希望这些是单独的词典,请改为创建appendic
的副本。 dict.copy()
方法创建字典的浅表副本:
dic['please_make_me_Foo']= appendic.copy()
dic['dont_make_him_Bar'] = appendic.copy()
Shallow意味着创建了一个新字典,并且复制了对包含的键和值的所有引用。
如果appendic
本身包含也是字典的值,则不会复制这些值。新副本和appendic
都会引用相同的值。在大多数情况下,这不是问题,因为大多数原始值(字符串,整数等)是不可变的,并且在用新的值替换这些值时,您从未注意到共享引用。
答案 1 :(得分:4)
你做了一个字典:
appendic= {
'Python_made_me':''
}
将其添加到您的其他词典两次
dic['please_make_me_Foo']= appendic
dic['dont_make_him_Bar'] = appendic
并设置单个字典的Python_made_me
值两次
dic['please_make_me_Foo']['Python_made_me'] = 'Foo'
dic['dont_make_him_Bar']['Python_made_me'] = 'Bar'
但是因为他们是相同的词典,第二行会覆盖第一行
如果您需要复制它,则需要使用copy
方法:
dic['please_make_me_Foo']= appendic.copy()
dic['dont_make_him_Bar'] = appendic.copy()
答案 2 :(得分:2)
dic['please_make_me_Foo']= appendic
dic['dont_make_him_Bar'] = appendic
appendic
是一个对象 - 您正在为dic
中的两个键分配对同一对象的引用。所以当你换一个时,你就改变了。
请改为尝试:
dic['please_make_me_Foo']= appendic.copy()
dic['dont_make_him_Bar'] = appendic.copy()
答案 3 :(得分:2)
hex(id(foo))
,您将获得foo
的内存地址,因此,让我们在以下示例中显示d
实例的地址,以使有形:
>>> hex(id(d))
'0x10bd95e60'
>>> hex(id(e[1]))
'0x10bd95e60'
>>> hex(id(f[1]))
'0x10bd95e60'
因此,如果您添加或删除e[1]
中的值,您实际上更改的是与d
指向的实例相同的实例,并且字典是可变的,即你可以改变其中的值。
现在您想知道为什么在处理整数时不会发生这种情况?因为事实上确实如此,只是整数不可变:
>>> i = 1
>>> hex(id(i))
'0x10ba51e90'
>>> j = i
>>> hex(id(j))
'0x10ba51e90'
>>> i = 2
>>> hex(id(i))
'0x10ba51eb0'
即。我指着记忆中的另一个地方。
通过使用类可以创建可变整数:
>>> class Integer:
... def __init__(self, i):
... self.i = i
...
>>> i = Integer(2)
>>> hex(id(i))
'0x10bd9b410'
>>> j = i
>>> hex(id(j))
'0x10bd9b410'
>>> j.i = 2
>>> i.i
2
>>> hex(id(i))
'0x10bd9b410'
要创建同一字典的新实例,您需要使用字典的copy()
成员:
>>> hex(id(d))
'0x10bd95e60'
>>> w = d.copy()
>>> x = d.copy()
>>> y = d.copy()
>>> hex(id(w))
'0x10bd96128'
>>> hex(id(x))
'0x10bd95f80'
>>> hex(id(y))
'0x10bd96098'