How does the below code work in Python:
a = input()
b = input()
a, b = b, a # STATEMENT 1
print(a, b)
Does the statement 1 create a third variable in Python heap memory space to swap the two numbers or does it use some algorithm to do the swap?
How does the below code work in Python:
a = input()
b = input()
a, b = b, a # STATEMENT 1
print(a, b)
Does the statement 1 create a third variable in Python heap memory space to swap the two numbers or does it use some algorithm to do the swap?
ruohola did a good job in providing the translated bytecode of the python code.
I am duplicating here for reference:
Python code:
a = input()
b = input()
a, b = b, a # STATEMENT 1
print(a, b)
Bytecode:
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
operation swaps the top 2 values of the python stack. So what do we actually have so far:
Python swaps the 2 values by calling a
swap
(ROT_TWO
) subroutine.
If this is how far you want to go and it answers your question it is fine.
However for those who want to go deeper and see how this swap (ROT_TWO
) subroutine works, 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();
}
Or in other words the implementation of ROT_TWO
actually performs the following steps (a
,b
are the top 2 values of the stack):
x1 = a
x2 = b
a = x2
b = x1
So the implementation uses auxiliary temporary locations (x1
, x2
) and in fact it uses 2 auxilliary memory locations instead of the minimum 1 auxiliary location to swap two values that a more memory-efficient implementation would do:
x = a
a = b
b = x
Under the current computing model, swapping two values can be done only in so many different ways and does not happen magically:
XOR
(or similar arithmetic) operationsSo to sum it up, Python under the hood indeed uses auxilliary temporary locations in order to swap the two values.
It's a simple bytecode operation which doesn't need any intermediate variables to do the swap. See this demo:
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
Note: Like bytecode as a whole, this is of course just an implementation detail of CPython.