python中交换两个值有种很方便的用法,如下
a, b = b, a
对于两侧都只有2或3个值的时候,它是通过栈stack来操作的
>>> import dis
>>> def foo(a, b):
... a, b = b, a
...
>>> dis.dis(foo)
2 0 LOAD_FAST 1 (b)
3 LOAD_FAST 0 (a)
6 ROT_TWO
7 STORE_FAST 0 (a)
10 STORE_FAST 1 (b)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
先把右侧的b, a放进栈里面(LOAD_FAST),那么根据栈先进后出的特性,会变成[a, b],然后通过ROT_TWO把两个值反转变成[b, a]。第一个STORE_FAST会先pop出b出来返回给a,然后第二个STORE_FAST把后面的a给pop出来给b,操作完成。
旋转ROT_TWO(rotate)的目的其实就是保证等号左侧的赋值顺序是从左到右的。
OK,现在开始讲一个坑了。
nums = [1,2,3,4,5,6,7]
nums[1], nums[nums[1]] = nums[nums[1]], nums[1] # 下意识会觉得将获得 [1, 3, 2, 4, 5, 6, 7]
print(nums)
下意识会觉得将获得 [1, 3, 2, 4, 5, 6, 7],然鹅答案是…
[1, 3, 3, 2, 5, 6, 7]
wtf ???
仔细思考后,发现是因为赋值是从左侧开始的,也就是说是nums[1]先被赋值。但是nums[1]被赋值后,后面的nums[nums[1]]中的nums[1]已经不是我们原来期待的了。
那么,把nums[1]和nums[nums[1]]的赋值顺序换一下就好了
nums = [1,2,3,4,5,6,7]
nums[nums[1]], nums[1] = nums[1], nums[nums[1]]
print(nums)
[1, 3, 2, 4, 5, 6, 7]
解决了,hhh。
参考文献:https://stackoverflow.com/questions/21047524/how-does-swapping-of-members-in-tuples-a-b-b-a-work-internally