Before asking, I read the accepted answer to the question "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)?"
I have a related question: Does Python automatically synchronize a variable whose value is a reference to another object? In other words, if I assign an object as the value of a variable, is the variable updated whenever the object is modified?
I have a specific problem where it appears that Python updates the value of a variable with an object as its value without any code explicitly triggering an update. I created a function that was supposed to be part of a solution to the ROT13 (rotate right 13 times) problem: shift an array to the right 13 times. Here is the function's code:
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)
The output of that code is wrong: [0, 0, 0, 0, 0, 0]
.
However, when I replace line 3 (backup = array
) with backup = [n for n in array]
, the answer is correct: [5, 0, 1, 2, 3, 4]
I inferred that whenever the for-loop executed, the value of backup
was updated because its value is inherently a reference to the object array
. It appears to me that when array[1]
was assigned the value zero, backup[1]
was also assigned zero instead of holding the value 1. Because of that, the for-loop simply assigned the value zero to every other variable in backup
thru array
.
If I instead assigned backup to a list object distinct from array
using backup = [n for n in array]
, modifying array
would not modify backup
.
What is the actual cause of this behavior?
In your example backup
and array
are both references to the same object. That is clear with this code example:
>>> array=[1,2,3,4]
>>> backup=array
>>> id(array)
4492535840
>>> id(backup)
4492535840
So your code is equivalent to this:
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)
Does that help?