python, 交换列表中的两个值遇到的坑

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值