变量赋值和修改(在python中)

Dou*_* AA 32 python variables list

当我运行这个脚本时(Python v2.6):

a = [1,2]
b = a
a.append(3)
print a
>>>> [1,2,3]
print b
>>>> [1,2,3]
Run Code Online (Sandbox Code Playgroud)

我期待print b输出[1,2].当我所做的一切都是改变时,为什么b会改变?是b永久绑在一个?如果是这样,我可以让它们独立吗?怎么样?

Pao*_*tti 56

Python中的内存管理涉及包含所有Python对象和数据结构的私有堆内存位置.

Python的运行时只处理对象的引用(它们都存在于堆中):Python堆栈上的内容总是引用其他地方的值.

>>> a = [1, 2]
Run Code Online (Sandbox Code Playgroud)

python变量

>>> b = a
Run Code Online (Sandbox Code Playgroud)

python变量

>>> a.append(3)
Run Code Online (Sandbox Code Playgroud)

python变量

在这里我们可以清楚地看到变量b绑定到同一个对象a.

您可以使用is运算符来测试两个对象在物理上是否相同,这意味着它们在内存中是否具有相同的地址.这也可以使用该id()功能进行测试.

>>> a is b
>>> True
>>> id(a) == id(b)
>>> True
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,您必须明确要求复制.完成后,两个不同的列表对象之间将不再有连接.

>>> b = list(a)
>>> a is b
>>> False
Run Code Online (Sandbox Code Playgroud)

python变量


Aar*_*ken 13

Python中的对象通过引用存储 - 您不是指定ato 的值b,而是指向指向的对象的指针a.

要按值模拟分配,您可以像这样制作副本:

import copy

b = copy.copy(a)

# now the code works as "expected"
Run Code Online (Sandbox Code Playgroud)

请注意,这有性能上的缺点.

在数组的情况下,有一个依赖切片的特殊方法:

b = a[:]

# code also works as expected here
Run Code Online (Sandbox Code Playgroud)

更新 - 除此之外,对于某些对象,您可以使用构造函数 - 这包括列表:

b = list(a)
Run Code Online (Sandbox Code Playgroud)

  • DiggyF在下面的注释中指出了这一点 - 出于可读性原因以及任何与numpy一起工作的东西,你会想要用`b = list(a)`替换`b = a [:]`. (2认同)