在问之前,我阅读了对问题"How do I pass a variable by reference?"的公认答案,并链接了相同答案中的文档:"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循环只为backup
中的所有其他变量分配了零值。通过array
。
如果我改为使用array
将备份分配给与backup = [n for n in array]
不同的列表对象,则修改array
不会修改backup
。
此行为的真正原因是什么?
没有同步进行。相反,只有一个列表。这两个变量都引用相同的列表–如果有帮助,您可以认为变量指向该列表或指向tagging it。您只对值执行操作,而不对变量执行操作,因此,鉴于只有一个列表,所有操作都会对其进行更改,并从同一列表中读取更改。
在您的示例中,backup
和array
都是对同一对象的引用。这个代码示例很清楚:
>>> 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)
有帮助吗?