pythonswapobject-reference

Python swap leads to unexpected results when order changes


Python supports 1-line A/B swap (A , B = B , A), and we would expect (B, A = A, B) would lead to the same result. However, I met a strange behavior when dealing with a list entry. I simplify my finding in the code below:

nums = [0, 0, 0, 0]
n = 2
print(nums, "expected case")
nums[n - 1], n = n, nums[n - 1]
print(n, nums)

nums = [0, 0, 0, 0]
n = 2
print(nums, "unexpected case")
n, nums[n - 1] = nums[n - 1], n
print(n, nums)

Below are output from executing the program above:

[0, 0, 0, 0] expected case
0 [0, 2, 0, 0]
[0, 0, 0, 0] unexpected case
0 [0, 0, 0, 2]

Question: why the order change above leads to different result? It appears that in the unexpected case, n gets assigned to 0 first, before nums[-1] gets updated.


Solution

  • Your assumption (that A, B = B, A and B, A = A, B are equivalent statement) is only true if A and B do not depend on each other. The problem is that in both cases, the right expression is what you expect it to be, but not the left one. In one case, n is assigned (to 0) before nums[n-1], so you actually access the 0-1=-1-nth case of the list (which is the last one, as shown by the example). In the other case, n-1 is computed before n is assigned again, so nums[n-1] corresponds to nums[1]. Keep in mind that expression are "evaluated" from left to right, even when assigning.