问题描述:
My intention is to swap elements in the list, and it works:
arr = [4,3,2,1,0]
idx = arr[0]
arr[0], arr[idx] = arr[idx], arr[0]
print(arr)
>> [0, 3, 2, 1, 4]
However this does not:
arr = [4,3,2,1,0]
arr[0], arr[arr[0]] = arr[arr[0]], arr[0]
print(arr)
>> [4, 3, 2, 1, 0]
How python evaluates the latter example?
解决方案 1:[1]
It’s easier to see what’s happening if you split the assignment into multiple statements.
arr[0], arr[arr[0]] = arr[arr[0]], arr[0]
is equivalent to:
temp = arr[arr[0]], arr[0] # temp = (0, 4)
arr[0] = temp[0] # arr[0] = 0
arr[arr[0]] = temp[1] # arr[0] = 4
Notice that arr[0]
is being updated before we assign to arr[arr[0]]
. That updated index is being used in the last assignment.
None of this ever reassigns arr[4]
, so it doesn’t swap the two elements.
解决方案 2:[2]
Let’s use the walrus operator (:=
) to gain some insight into what’s happening.
>>> arr = [4, 3, 2, 1, 0]
>>> arr[0], arr[a := arr[0]] = arr[b := arr[0]], arr[0]
>>> arr
[4, 3, 2, 1, 0]
>>> a
0
>>> b
4
Now if we rework this slightly:
>>> arr = [4,3,2,1,0]
>>> arr[0], arr[b] = arr[b := arr[0]], arr[0]
>>> print(arr)
[0, 3, 2, 1, 4]
What’s happening is similar to the unexpected behavior programmers see when modifying a collection while iterating over it.
参考链接:
Copyright Notice: This article follows StackOverflow’s copyright notice requirements and is licensed under CC BY-SA 3.0.
Article Source: StackOverflow
[1] Barmar
[2] Chris