python:如何解释以下代码

时间:2016-08-25 18:40:23

标签: python

在我的本地机器上测试:

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会这样做?在哪种情况下,会发生这种行为?

由于

3 个答案:

答案 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”值也会相同。

For any reference regarding the same topic