一、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内置模块dis
的dis
方法进行查看,具体代码如下。
>>> 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
- 所以,就造成了整体结果与我们的期望相去甚远。