变量赋值与修改(在python中)[重复]
- 2025-02-25 09:07:00
- admin 原创
- 19
问题描述:
当我运行此脚本(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]
。为什么我所做的只是更改 a,而 b 却发生了变化?b 是否永久绑定到 a?如果是,我可以将它们独立吗?怎么做?
解决方案 1:
Python 中的内存管理涉及包含所有 Python 对象和数据结构的私有堆内存位置。
Python 的运行时仅处理对对象(所有对象都位于堆中)的引用:Python 堆栈中发生的始终是对位于其他地方的值的引用。
>>> a = [1, 2]
>>> b = a
>>> a.append(3)
这里我们可以清楚的看到变量b
与绑定到了同一个对象a
。
您可以使用is
运算符来测试两个对象是否在物理上相同,即它们在内存中是否具有相同的地址。也可以使用id()
函数来测试。
>>> a is b
>>> True
>>> id(a) == id(b)
>>> True
因此,在这种情况下,您必须明确请求复制。一旦您这样做了,两个不同的列表对象之间将不再有任何联系。
>>> b = list(a)
>>> a is b
>>> False
解决方案 2:
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)
解决方案 3:
简短的回答——指针。
当您输入时,b = a
它设置b
为查看相同的数组a
。您必须创建一个新数组,其中包含元素的副本以将它们分开。在这种情况下,类似的东西b = [n for n in a]
就可以正常工作。对于更复杂的操作,您可能需要查看http://docs.python.org/library/copy.html。
解决方案 4:
您可能需要查看此链接。您在这里遇到的问题是a
两者b
都指向相同的内存位置,因此更改其中一个会更改另一个。相反,您需要执行以下操作:
a = [1,2]
b = list(a)
解决方案 5:
a
是指向列表的指针[1,2]
。
当您进行分配时,b = a
b 的值是列表的地址[1,2]
。
因此,当您这样做时,您a.append(3)
实际上并没有改变,而是改变了指向a
的列表。由于和都指向同一个列表,因此当您修改另一个时,它们似乎都会发生变化。a
`a`b
解决方案 6:
如果你只是想将列表 a 的内容复制到 b,而不是将 b 指针指向 a:
b = a[:]
使用切片运算符将把列表的内容复制到 b 中,这样您的示例将变成:
a = [1,2]
b = a[:]
a.append(3)
print a
>>>> [1,2,3]
print b
>>>> [1,2]