在Python中如何实现交换变量?

问题描述 投票:2回答:1

下面的代码在Python中是如何实现的。

a = input()
b = input()
a, b = b, a  # STATEMENT 1
print(a, b)

语句1是在Python堆内存空间中创建第三个变量来交换这两个数字,还是使用某种算法来完成交换?

python algorithm swap
1个回答
4
投票

这是一个简单的字节码操作,不需要任何中间变量来完成交换。请看这个演示。

import dis

code = '''
a = input()
b = input()
a, b = b, a
'''

dis.dis(code)

输出。

 2           0 LOAD_NAME                0 (input)
             2 CALL_FUNCTION            0
             4 STORE_NAME               1 (a)

 3           6 LOAD_NAME                0 (input)
             8 CALL_FUNCTION            0
            10 STORE_NAME               2 (b)

 4          12 LOAD_NAME                2 (b)
            14 LOAD_NAME                1 (a)
            16 ROT_TWO
            18 STORE_NAME               1 (a)
            20 STORE_NAME               2 (b)
            22 LOAD_CONST               0 (None)
            24 RETURN_VALUE

注:和字节码整体一样,这当然只是 CPython 的一个实现细节。


2
投票

ruohola 做得很好,提供了python代码的翻译字节码。

我在这里重复一下,以供参考。

Python代码:

a = input()
b = input()
a, b = b, a  # STATEMENT 1
print(a, b)

字节码:

 2           0 LOAD_NAME                0 (input)
             2 CALL_FUNCTION            0
             4 STORE_NAME               1 (a)

 3           6 LOAD_NAME                0 (input)
             8 CALL_FUNCTION            0
            10 STORE_NAME               2 (b)

 4          12 LOAD_NAME                2 (b)
            14 LOAD_NAME                1 (a)
            16 ROT_TWO                  # swapping done here
            18 STORE_NAME               1 (a)
            20 STORE_NAME               2 (b)
            22 LOAD_CONST               0 (None)
            24 RETURN_VALUE

ROT_TWO 操作交换python堆栈的前两个值。那么到目前为止,我们实际上有什么。

Python通过调用 swap (ROT_TWO)子程序。

如果这是你想走的路,而且它回答了你的问题,这是很好的.然而对于那些想深入了解这个交换(ROT_TWO)子程序工作。这里是官方的CPython实现:

#define TOP()             (stack_pointer[-1])
#define SECOND()          (stack_pointer[-2])
#define SET_TOP(v)        (stack_pointer[-1] = (v))
#define SET_SECOND(v)     (stack_pointer[-2] = (v))
/*..*/
case TARGET(ROT_TWO): {
   PyObject *top = TOP();
   PyObject *second = SECOND();
   SET_TOP(second);
   SET_SECOND(top);
   FAST_DISPATCH();
}

或者换句话说,实施 ROT_TWO 实际上执行了以下步骤(a,b 是堆栈的前2个值)。)

x1 = a
x2 = b
a = x2
b = x1

所以执行 使用辅助性临时地点 (x1, x2),事实上它使用了2个辅助内存位置,而不是像更节省内存的实现那样,用最少1个辅助位置来交换两个值。

x = a
a = b
b = x

在目前的计算模式下, 交换两个值只能用这么多不同的方法来完成。 而不会神奇地发生。

  1. 使用辅助的临时存储
  2. 采用一系列的 XOR 运算

所以,综上所述,Python在引擎盖下确实使用了辅助的临时位置来交换两个值。

© www.soinside.com 2019 - 2024. All rights reserved.