Python通过分配复制?

Mar*_*row 43 python

我希望下面的代码只会初始化dict_a,dict_b以及dict_c字典.但它接触到副本通过效果:

dict_a = dict_b = dict_c = {}
dict_c['hello'] = 'goodbye'

print dict_a
print dict_b
print dict_c
Run Code Online (Sandbox Code Playgroud)

如您所见,结果如下:

{'hello': 'goodbye'}
{'hello': 'goodbye'}
{'hello': 'goodbye'}
Run Code Online (Sandbox Code Playgroud)

为什么该程序会给出以前的结果,当我希望它返回时:

{}
{}
{'hello': 'goodbye'}
Run Code Online (Sandbox Code Playgroud)

dan*_*ben 43

这是因为在Python中,变量(名称)只是对单个对象的引用.当您指定dict_a = dict_b,你真的复制存储器地址(或指针,如果你愿意)从dict_bdict_a.那个词典还有一个例子.

要获得所需的行为,请使用该dict.copy方法,或者copy.deepcopy在您的dict可能具有嵌套的dicts或其他嵌套对象时使用.

>>> a = {1:2}
>>> b = a.copy()
>>> b
{1: 2}
>>> b[3] = 4
>>> a
{1: 2}
>>> b
{1: 2, 3: 4}
>>> 
Run Code Online (Sandbox Code Playgroud)

  • 一切都是一个对象,变量是我们分配给对象的名称(而不是相反的方式!)所以如果你做`a = b = c = 1; a + = 1`,然后将所有内容分配给对象"1",然后将"a"分配给对象"2".对于像列表,字符串和集合这样的可变对象,您可以更改对象本身,这将由分配给该对象的所有名称看到,但是使用整数,字符串,元组和其他不可变对象,您可以做的就是分配名称到另一个对象. (12认同)
  • 无论如何,Python 中的一切都是对象。要查看属于整数对象 1 的函数,您可以执行 `dir(1)`。 (2认同)
  • *“对象只是引用”*这不是真的。物体就是物体。名字引用了他们。 (2认同)

Jef*_*ose 8

即使

>>> dict_a, dict_b, dict_c = {}, {}, {}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下是正确的方法,当它超过3时看起来很奇怪

想像

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
Run Code Online (Sandbox Code Playgroud)

如果我想初始化超过3件事,我会使用

>>> a, b, c, d, e, f, = [dict() for x in range(6)]
Run Code Online (Sandbox Code Playgroud)

注意:不要使用__CODE__

  • 杰弗里何塞:怀疑托马斯?`import dis; print dis.dis(lambda:dict()); print dis.dis(lambda:{})` (6认同)
  • "注意:不要在范围(6)中使用[{}代表x"为什么不呢?每次迭代都会执行一次元素表达式,每次执行文字"{}"时,它都会返回一个新的dict.实际上,这应该优于`dict()`,因为它避免了函数调用. (3认同)