Python 交换列表内两位置的元素遇到的问题


一、Python连续赋值

例子:

lt = [1, 3, 5, 2, 0]

对上边的列表执行以下的操作:

1. 赋值1

lt[0], lt[lt[0]] = lt[lt[0]], lt[0]

那么其结果是什么呢?结果是这个吗:

[3,1,5,2,0]

结果是否定的,最终结果实际上是

[3,3,5,1, 0]

2. 赋值2

lt[lt[0]], lt[0] = lt[0], lt[lt[0]]

那么这次结果是什么呢?实际上这次的结果才是我们所希望的。

[3, 1, 5, 2, 0]

为什么这样写就对,第一种写法却不对呢?下边解释

二、解释

首先解释一下Python连续赋值的原理,Python会首先将赋值号=右边的值打包成一个元祖,然后再解包,对=左边的变量从左至右依次赋值。这个执行顺序可以通过Python内置模块disdis方法进行查看,具体代码如下。

>>> import dis
>>> dis.dis('lt[0], lt[lt[0]] = lt[lt[0]], lt[0]')

执行结果如下:

1 0 LOAD_NAME 0 (lt)
2 LOAD_NAME 0 (lt)
4 LOAD_CONST 0 (0)
6 BINARY_SUBSCR
8 BINARY_SUBSCR
10 LOAD_NAME 0 (lt)
12 LOAD_CONST 0 (0)
14 BINARY_SUBSCR
16 ROT_TWO
18 LOAD_NAME 0 (lt)
20 LOAD_CONST 0 (0)
22 STORE_SUBSCR
24 LOAD_NAME 0 (lt)
26 LOAD_NAME 0 (lt)
28 LOAD_CONST 0 (0)
30 BINARY_SUBSCR
32 STORE_SUBSCR
34 LOAD_CONST 1 (None)
36 RETURN_VALUE

因此我们可以得出结论,

  • Python会先将lt[lt[0]]lt[0]位置的值打包成一个元祖(3, 1)
  • 接下来从左至右开始赋值,首先就是给lt[0]赋值,lt[0]位置的值等于3
  • 接下来给lt[lt[0]]位置赋值,但是因为lt[0]位置的值已经改变,所以接下来给lt[lt[0]]赋值实际上就变成了给lt[3]位置赋值,原本应该是lt[1]。所以lt[3]位置的值就变成了1
  • 所以,就造成了整体结果与我们的期望相去甚远。

文章作者: Arvin He
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Arvin He !
评论
 上一篇
剑指Offer 04. 二维数组中的查找 剑指Offer 04. 二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
2020-10-25
下一篇 
  目录