Python 中如何实现交换变量?
How swapping variables is implemented in Python?
下面的代码在 Python 中如何工作:
a = input()
b = input()
a, b = b, a # STATEMENT 1
print(a, b)
语句 1 是否在 Python 堆内存 space 中创建了第三个变量来交换两个数字,或者它是否使用某种算法来进行交换?
这是一个简单的字节码操作,不需要任何中间变量来进行交换。请参阅此演示:
import dis
code = '''
a = input()
b = input()
a, b = b, a
'''
dis.dis(code)
Output:
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的一个实现细节。
在提供 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 堆栈的前 2 个值。那么到目前为止我们实际上有什么:
Python swaps the 2 values by calling a swap
(ROT_TWO
) subroutine.
如果这是您想要达到的程度并且它回答了您的问题,那很好。
然而,对于那些想要更深入了解此交换 (ROT_TWO
) 子例程如何工作的人,here is the official CPython implementation:
#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
在当前的计算模型下,swapping two values can be done only in so many different ways并不会神奇地发生:
- 使用辅助临时存储
- 采用一系列
XOR
(或类似的算术)运算
所以总而言之,Python在幕后确实使用辅助临时位置来交换两个值。
下面的代码在 Python 中如何工作:
a = input()
b = input()
a, b = b, a # STATEMENT 1
print(a, b)
语句 1 是否在 Python 堆内存 space 中创建了第三个变量来交换两个数字,或者它是否使用某种算法来进行交换?
这是一个简单的字节码操作,不需要任何中间变量来进行交换。请参阅此演示:
import dis
code = '''
a = input()
b = input()
a, b = b, a
'''
dis.dis(code)
Output:
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的一个实现细节。
我在这里复制以供参考:
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 堆栈的前 2 个值。那么到目前为止我们实际上有什么:
Python swaps the 2 values by calling a
swap
(ROT_TWO
) subroutine.
如果这是您想要达到的程度并且它回答了您的问题,那很好。
然而,对于那些想要更深入了解此交换 (ROT_TWO
) 子例程如何工作的人,here is the official CPython implementation:
#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
在当前的计算模型下,swapping two values can be done only in so many different ways并不会神奇地发生:
- 使用辅助临时存储
- 采用一系列
XOR
(或类似的算术)运算
所以总而言之,Python在幕后确实使用辅助临时位置来交换两个值。