在我的本地机器上测试:
Python 2.7.3 (default, Jun 22 2015, 19:33:41)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> q=[2,3]
>>> p=[1,q,4]
>>> p[1].append('test')
>>> q
[2, 3, 'test']
>>> hex(id(q))
'0x7fabfa5c2b90'
>>>
>>>
>>> hex(id(p))
'0x7fabfa5c2b48'
>>> hex(id(p[1]))
'0x7fabfa5c2b90'
>>>
>>>
>>> p.append(q)
>>> p
[1, [2, 3, 'test'], 4, [2, 3, 'test']]
>>> p[1].append('test2')
>>> p
[1, [2, 3, 'test', 'test2'], 4, [2, 3, 'test', 'test2']]
>>>
一开始,我想在生成p时,q的副本被复制到p中。
任何文件都有助于理解上述行为?我不知道为什么python会这样做?在哪种情况下,会发生这种行为?
由于
答案 0 :(得分:3)
当您将q
追加到p
时,您没有创建q
的副本,实际上是在追加名称q
当前指向的对象的引用至。因此,当您追加到q
(或者在这种情况下p[1]
,它指向同一个对象)时,它将追加到这两个引用所指向的单个对象。如果要插入q
的副本,可以像这样使用切片:
p=[1,q[:],4]
或
p.append(q[:])
这将创建一个新的匿名列表,您可以附加到该列表,而不会影响q
指向的同一对象的原始或任何其他引用。
以下是一个例子:
>>> q = [2, 3]
>>> p = [1, q[:], 4] # include a copy of q using [:]
>>> p[1].append('test') # append to copy
>>> p
[1, [2, 3, 'test'], 4] # 'test' is in p[1]
>>> q
[2, 3] # but not in q
>>> p = [1, q, 4] # include q itself in p (no [:])
>>> p[1].append('test')
>>> p
[1, [2, 3, 'test'], 4] # test appears in p[1]
>>> q
[2, 3, 'test'] # and also in q
答案 1 :(得分:1)
好吧,我可以解释一下。您的p
会引用q
,但您无法更改。就这样。因此,如果您要修改p[1]
,那么基本上它会修改q
,因为它会通过引用进行修改。
任何文档都有助于理解上述行为? https://docs.python.org/2/reference/datamodel.html
我不知道为什么python会这样做?
有两种做事方式。
基于对象的引用(您不会将q
的副本传递给p
,只需参考):
>>> q=[2,3]
>>> p=[1,q,4]
>>> p[1].append('test')
>>> q
[2, 3, 'test']
没有(您将q
的副本传递给p
,而不是参考):
>>> q=[2,3]
>>> p=[1,q[:],4]
>>> p[1].append('test')
>>> q
[2, 3]
在哪种情况下会发生这种情况?
我认为上面的例子显示了它。
答案 2 :(得分:1)
如果您是Python新手,可能会遇到类似这样的问题。
在Python中如果你说
b = a
然后说
from copy import copy
b = copy(a)
会发生什么? b得到a的值,但是a中的任何变化都会使b中发生类似的变化,因为不是仅仅复制值“b”指向“a”(这意味着a中的变化也会反映在b中) 这就是你面临这个问题的原因。
如果您不想这样,可以在python中使用复制模块
nodejs
现在即使您更改“a”的值,“b”值也会相同。