Python 是否自动更新值为另一个对象的变量?

Does Python automatically update variables whose value is another object?

在提问之前,我阅读了问题"How do I pass a variable by reference?" and documentation linked in that same answer: "How do I write a function with output parameters (call by reference)?"

的已接受答案

我有一个相关的问题:Python 是否自动同步一个变量,其值是对另一个对象的引用?换句话说,如果我将一个对象赋值给一个变量,那么这个对象被修改时变量是否更新?

我有一个特定的问题,似乎 Python 使用对象更新变量的值作为其值,而没有任何代码显式触发更新。我创建了一个函数,它应该是 ROT13(向右旋转 13 次)问题的解决方案的一部分:将数组向右移动 13 次。这是函数的代码:

array = [0, 1, 2, 3, 4, 5]
print(array)
backup = array

#backup = [n for n in array]

for i in range( 1, (len(backup)) ):
    array[i] = backup[i - 1]

array[0] = backup[-1]
backup = array
print(array)

该代码的输出是错误的:[0, 0, 0, 0, 0, 0]。 但是,当我将第 3 行 (backup = array) 替换为 backup = [n for n in array] 时,答案是正确的:[5, 0, 1, 2, 3, 4]

我推断,每当执行 for 循环时,backup 的值都会更新,因为它的值本质上是对对象 array 的引用。在我看来,当 array[1] 被赋值为零时, backup[1] 也被赋值为零而不是保持值 1。因此,for 循环简单地将值零赋给每个其他变量在 backuparray.

如果我改为使用 backup = [n for n in array] 将备份分配给与 array 不同的列表对象,则修改 array 不会修改 backup.

此行为的实际原因是什么?

在您的示例中,backuparray 都是对同一对象的引用。这个代码示例很清楚:

>>> array=[1,2,3,4]
>>> backup=array
>>> id(array)
4492535840
>>> id(backup)
4492535840

所以你的代码等同于:

array = [0, 1, 2, 3, 4, 5]
print(array)

for i in range( 1, (len(array)) ):
    array[i] = array[i - 1]

array[0] = array[-1]
print(array)

有帮助吗?

没有进行同步。相反,只有一个列表。两个变量都引用同一个列表——如果有帮助,您可以将变量视为指向它或 tagging it。您对值而不是变量执行操作,因此假设只有一个列表,所有操作都会更改它并从同一个列表中读取更改。