Why don't Python dictionaries treat keys independently in this script?
我期待着我的挫折会被一些启示所覆盖-下面是一个演示这个问题的脚本的最小版本:
首先,我创建一个字典:
1 2 3 4 | dic = { 'foo':{}, 'bar':{} } |
然后我们实例化一个模板字典,它可以被迭代附加至
1 2 3 | appendic= { 'is':'', # '' is a terminal value to be replaced later } |
号
在这里,我们将EDOCX1[1]附加到EDOCX1[0]中的每个键:
1 2 | dic['foo'] = appendic dic['bar'] = appendic |
现在,我们用一些有意义的东西替换终端值"":
1 2 | dic['foo']['is'] = 'foo' dic['bar']['is'] = 'bar' |
。
此时,我的直觉告诉我,如果我们调用:
但相反,python返回
问题:
- 如何告诉python保持dic的键独立?
- 为什么这是默认行为?这有什么用例?
当您将一个
因此,
如果您希望这些字典是单独的,请创建一个
1 2 | dic['please_make_me_Foo']= appendic.copy() dic['dont_make_him_Bar'] = appendic.copy() |
。
Shallow意味着创建了一个新字典,并且复制了对所包含键和值的所有引用。
如果
你做口述:
1 2 3 | appendic= { 'Python_made_me':'' } |
把它加到你的另一个口述里两次
1 2 | dic['please_make_me_Foo']= appendic dic['dont_make_him_Bar'] = appendic |
号
将单个dict的
1 2 | dic['please_make_me_Foo']['Python_made_me'] = 'Foo' dic['dont_make_him_Bar']['Python_made_me'] = 'Bar' |
但是因为它们是同一个dict,所以第二行覆盖了第一行
如果需要复制,需要使用
1 2 | dic['please_make_me_Foo']= appendic.copy() dic['dont_make_him_Bar'] = appendic.copy() |
。
好的,我只写这个作为对其他答案的补充。当您操纵字典时,您操纵对实例的引用,这是错误的根本原因。使用
1 2 3 4 5 6 | >>> hex(id(d)) '0x10bd95e60' >>> hex(id(e[1])) '0x10bd95e60' >>> hex(id(f[1])) '0x10bd95e60' |
因此,如果您从
现在你想知道,为什么处理整数时不会发生这种情况?因为,事实上,整数是不可变的:
1 2 3 4 5 6 7 8 9 | >>> i = 1 >>> hex(id(i)) '0x10ba51e90' >>> j = i >>> hex(id(j)) '0x10ba51e90' >>> i = 2 >>> hex(id(i)) '0x10ba51eb0' |
。
也就是说,我指的是记忆中的另一个地方。
但是,可以通过使用类来创建可变整数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> 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' |
要创建同一词典的新实例,需要使用dict的
1 2 3 4 5 6 7 8 9 10 11 | >>> 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' |
。
1 2 | dic['please_make_me_Foo']= appendic dic['dont_make_him_Bar'] = appendic |
号
试试这个:
1 2 | dic['please_make_me_Foo']= appendic.copy() dic['dont_make_him_Bar'] = appendic.copy() |
。