2

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?

YoungMoon
  • 31
  • 3

1 Answers1

5

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
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271