variables赋值和修改(在Python中)

当我运行这个脚本(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是永久性的吗? 如果是的话,我可以让他们独立吗? 怎么样?

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

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

 >>> a = [1, 2] 

python变量

 >>> b = a 

python变量

 >>> a.append(3) 

python变量

在这里我们可以清楚地看到variablesb被绑定到与a相同的对象。

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

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

所以,在这种情况下, 你必须明确地要求一个副本 。 一旦你这样做了,两个不同的列表对象之间就不会有更多的连接。

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

python变量

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

要按值来模拟分配,你可以像这样做一个副本:

 import copy b = copy.copy(a) # now the code works as "expected" 

请注意这有性能上的缺点。

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

 b = a[:] # code also works as expected here 

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

 b = list(a) 

简短的回答 – 指针。

当你键入b = a它将设置b来查看看起来相同的数组。 你必须用元素的副本来创build一个新的数组来分离它们。 在这种情况下,像b = [n for n in a]就可以正常工作。 对于更复杂的操作,你可能想看看http://docs.python.org/library/copy.html

你可能想看看这个链接。 你在这里a的问题是ab都指向相同的内存位置,所以更改一个会改变另一个。 相反,你想要做这样的事情:

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

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

当你进行赋值b = a ,b的值就是列表的地址[1,2]

所以当你做a.append(3)你实际上并没有改变,你正在改变a指向的列表。 由于ab都指向相同的列表,所以在修改其他列表时它们都会发生更改。

如果您只是简单地将列表a的内容复制到b,而不是将ba指针指向a:

 b = a[:] 

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

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