下面的代码在Python中是如何实现的。
a = input()
b = input()
a, b = b, a # STATEMENT 1
print(a, b)
语句1是在Python堆内存空间中创建第三个变量来交换这两个数字,还是使用某种算法来完成交换?
这是一个简单的字节码操作,不需要任何中间变量来完成交换。请看这个演示。
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 的一个实现细节。
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
在目前的计算模式下, 交换两个值只能用这么多不同的方法来完成。 而不会神奇地发生。
XOR
运算所以,综上所述,Python在引擎盖下确实使用了辅助的临时位置来交换两个值。