python为什么更改列表y也会更改列表x?

python

如果你编写的代码就像下面一样:

>>>

>>> x=[]

>>> y=x

>>> y.append(10)

>>> y

[10]

>>> x

[10]

你可能想知道为什么追加一个元素也改变了x。

产生这种结果有两个因素:

  1. 变量只是指向具体对象的名称。 执行 y=x 并不会为列表创建一个副本 —— 它只是创建了一个新变量 y 指向 x 所指向的同一对象。 这意味着只存在一个对象(列表),xy 都是对它的引用。

  2. 列表属于 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

我们可以看到在此情况下 xy 就不再相等了。 这是因为整数是 immutable 对象,当我们执行 x=x+1 时我们并不是改变了 5 这个对象的值;而是创建了一个新的对象 (整数 6) 并将其赋值给 x (也就是改变了 x 所指向的对象)。 在赋值之后我们就有了两个对象 (整数 65) 以及分别指向它们的两个变量 (x 现在指向 6y 仍然指向 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

回到顶部