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

时间:2011-07-22 17:36:47

标签: python list variables

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

a = [1,2]
b = a
a.append(3)
print a
>>>> [1,2,3]
print b
>>>> [1,2,3]

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

6 个答案:

答案 0 :(得分:48)

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

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

>>> a = [1, 2]

python variables

>>> b = a

python variables

>>> a.append(3)

python variables

在这里,我们可以清楚地看到变量ba绑定在同一个对象上。

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

>>> a is b
>>> True
>>> id(a) == id(b)
>>> True

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

>>> b = list(a)
>>> a is b
>>> False

python variables

答案 1 :(得分:13)

Python中的对象是通过引用存储的 - 您没有将a的值赋给b,而是指向a指向的对象的指针。

要按值模拟分配,您可以制作如下副本:

import copy

b = copy.copy(a)

# now the code works as "expected"

请注意这有性能劣势。

对于数组,有一种依赖切片的特殊方法:

b = a[:]

# code also works as expected here

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

b = list(a)

答案 2 :(得分:4)

简短回答 - 指针。

当您输入b = a时,它会设置b以查看a查看的相同数组。您必须创建一个包含元素副本的新数组以将它们分开。在这种情况下,像b = [n for n in a]这样的东西可以正常工作。对于更复杂的操作,您可能需要查看http://docs.python.org/library/copy.html

答案 3 :(得分:4)

您可能需要查看this链接。您遇到的问题是ab都指向相同的内存位置,因此更改另一个会更改另一个内存位置。相反,你想做这样的事情:

a = [1,2]
b = list(a)

答案 4 :(得分:3)

a是指向列表[1,2]的指针。

执行作业b = a时,b的值是列表[1,2]的地址。

因此,当您执行a.append(3)时实际上并未更改a,您正在更改a指向的列表。由于ab都指向同一个列表,因此当您修改另一个列表时,它们似乎都会发生变化。

答案 5 :(得分:2)

如果您只是想将列表a的内容复制到b,而不是将b指向a:

b = a[:]

使用切片运算符会将列表的内容复制到b中,以便您的示例变为:

a = [1,2]
b = a[:]
a.append(3)
print a
>>>> [1,2,3]
print b
>>>> [1,2]