The following code block does not work.
a = [2,1,3]
i = 1
a[i], a[a[i]-1] = a[a[i]-1], a[i]
Whereas this does.
a = [2,1,3]
i = 1
j = a[i]-1
a[i], a[j] = a[j], a[i]
Does anyone know?
The left side of the equals is assigned from left to right, and each term is only evaluated as it's reached. This means that:
a[i], a[a[i]-1] = a[a[i]-1], a[i]
is equivalent to:
tmp = a[a[i]-1], a[i]
a[i] = tmp[0] # Changes a[i]
a[a[i]-1] = tmp[1] # USES new a[i] to determine assignment index!!!
which makes it clear that the assignment to a[i]
finishes, then the new value of a[i]
is used to compute the index of the second assignment.
Your working code works because it caches the old value of a[i]
, so reassigning a[i]
doesn't change where the second value goes; the equivalent code there making that clear:
j = a[i]-1 # Caches old a[i]
tmp = a[j], a[i]
a[i] = tmp[0] # Changes a[i]
a[j] = tmp[1] # Changes using original a[i] as intended