python交换和赋值

时间:2014-07-06 22:37:05

标签: python swap

通常,我们使用A[i], A[j] = A[j], A[i]进行交换。

这有时可能无效。例如,

A=[1, 2]
A[0], A[A[0]] = A[A[0]], A[0]

会失败。为什么它会失败以及如何解释赋值?

1 个答案:

答案 0 :(得分:6)

让我们看一下有关语句的字节码:

>>> 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[A[0]]在分配到A[0]之后才会被评估。

作为修复,我建议:

A0 = A[0]
A[0], A[A0] = A[A0], A[0]