python为什么更改列表y也会更改列表x?
如果你编写的代码就像下面一样:
>>> x=[]>>> y=x
>>> y.append(10)
>>> y
[10]
>>> x
[10]
你可能想知道为什么追加一个元素也改变了x。
产生这种结果有两个因素:
变量只是指向具体对象的名称。 执行
y=x
并不会为列表创建一个副本 —— 它只是创建了一个新变量y
指向x
所指向的同一对象。 这意味着只存在一个对象(列表),x
和y
都是对它的引用。列表属于 mutable 对象,这意味着你可以改变它的内容。
在调用 append()
之后,这个可变对象的内容由 []
变为 [10]
。 由于两个变量都指向同一对象,因此使用任何一个名称所访问到的都是修改后的值 [10]
。
如果我们改为将不可变对象赋值给 x
:
>>> x=5# ints are immutable>>> y=x
>>> x=x+1# 5 can"t be mutated, we are creating a new object here
>>> x
6
>>> y
5
我们可以看到在此情况下 x
和 y
就不再相等了。 这是因为整数是 immutable 对象,当我们执行 x=x+1
时我们并不是改变了 5
这个对象的值;而是创建了一个新的对象 (整数 6
) 并将其赋值给 x
(也就是改变了 x
所指向的对象)。 在赋值之后我们就有了两个对象 (整数 6
和 5
) 以及分别指向它们的两个变量 (x
现在指向 6
而 y
仍然指向 5
)。
某些操作 (例如 y.append(10)
和 y.sort()
) 是改变原对象,而看上去相似的另一些操作 (例如 y=y+[10]
和 sorted(y)
) 则是创建新对象。 通常在 Python 中 (以及在标准库的所有代码中) 会改变原对象的方法将返回 None
以帮助避免混淆这两种不同类型的操作。 因此如果你错误地使用了 y.sort()
并期望它将返回一个经过排序的 y
的副本,你得到的结果将会是 None
,这将导致你的程序产生一个容易诊断的错误。
但是,还存在一类操作,不同的类型执行相同的操作会有不同的行为:那就是增强赋值运算符。 例如,+=
会原地改变列表,但不会改变元组或整数 (a_list+=[1,2,3]
与 a_list.extend([1,2,3])
一样都会改变 a_list
,而 some_tuple+=(1,2,3)
和 some_int+=1
则会创建新的对象)。
换而言之:
如果我们有一个可变对象 (
list
,dict
,set
等等),我们可以使用某些特定的操作来改变它,所有指向它的变量都会显示它的改变。如果我们有一个不可变对象 (
str
,int
,tuple
等等),所有指向它的变量都将显示相同样的值,但凡是会改变这个值的操作将总是返回一个新对象。
如果你想知道两个变量是否指向相同的对象,你可以使用 is
运算符,或内置函数 id()
。
以上是 python为什么更改列表y也会更改列表x? 的全部内容, 来源链接: utcz.com/z/520599.html