让我们看看有问题的语句的字节码:
>>> def f(A):
... A[0], A[A[0]] = A[A[0]], A[0]
...
>>> dis.dis(f)
2 0 LOAD_FAST 0 (A)
3 LOAD_FAST 0 (A)
6 LOAD_CONST 1 (0)
9 BINARY_SUBSCR
10 BINARY_SUBSCR
11 LOAD_FAST 0 (A)
14 LOAD_CONST 1 (0)
17 BINARY_SUBSCR
18 ROT_TWO
19 LOAD_FAST 0 (A)
22 LOAD_CONST 1 (0)
25 STORE_SUBSCR
26 LOAD_FAST 0 (A)
29 LOAD_FAST 0 (A)
32 LOAD_CONST 1 (0)
35 BINARY_SUBSCR
36 STORE_SUBSCR
37 LOAD_CONST 0 (None)
40 RETURN_VALUE
这样工作如下:
>指令0-10在值堆栈上按A [A [0]],因此为2
>指令11-17在值堆栈上按A [0],现在为2,1
>指令18交换它们,堆栈为1,2
>指令19-25将最高值(2)分配给A [0],将值堆栈保留为1
>指令26-36尝试为A [A [0]]赋值,但A [0]现在为2,所以它试图分配给A [2],这是一个IndexError.
简而言之,问题是在分配给A [0]之后才评估左侧的A [A [0]].
作为修复,我建议:
A0 = A[0]
A[0], A[A0] = A[A0], A[0]