Prerequisites - 2 important Points
Lists are mutable
The main part in lists is that lists are mutable. It means that the
values of lists can be changed. This is one of the reason why you are
facing the trouble. Refer the docs for more info
Order of Evaluation
The other part is that while unpacking a tuple, the evaluation starts
from left to right. Refer the docs for more info
Introduction
when you do a,b = c,d
the values of c
and d
are first stored. Then starting from the left hand side, the value of a
is first changed to c
and then the value of b
is changed to d
.
The catch here is that if there are any side effects to the location of b
while changing the value of a
, then d
is assigned to the later b
, which is the b
affected by the side effect of a
.
Use Case
Now coming to your problem
In the first case,
nums = [1, 2, 0]
nums[nums[0]], nums[0] = nums[0], nums[nums[0]]
nums[0]
is initially 1
and nums[nums[0]]
is 2
because it evaluates to nums[1]
. Hence 1,2 is now stored into memory.
Now tuple unpacking happens from left hand side, so
nums[nums[0]] = nums[1] = 1 # NO side Effect.
nums[0] = 2
hence print nums
will print [2, 1, 0]
However in this case
nums = [1, 2, 0]
nums[0], nums[nums[0]] = nums[nums[0]], nums[0]
nums[nums[0]], nums[0]
puts 2,1 on the stack just like the first case.
However on the left hand side, that is nums[0], nums[nums[0]]
, the changing of nums[0]
has a side effect as it is used as the index in nums[nums[0]]
. Thus
nums[0] = 2
nums[nums[0]] = nums[2] = 1 # NOTE THAT nums[0] HAS CHANGED
nums[1]
remains unchanged at value 2
. hence print nums
will print [2, 2, 1]