In [55]: a = 5
In [56]: b = 6
In [57]: (a, b) = (b, a)
In [58]: a
Out[58]: 6
In [59]: b
Out[59]: 5
How does this swapping of values of a and b work internally? Its definitely not using a temp variable.
In [55]: a = 5
In [56]: b = 6
In [57]: (a, b) = (b, a)
In [58]: a
Out[58]: 6
In [59]: b
Out[59]: 5
How does this swapping of values of a and b work internally? Its definitely not using a temp variable.
Copyright © 2021 Jogjafile Inc.
Python separates the right-hand side expression from the left-hand side assignment. First the right-hand side is evaluated, and the result is stored on the stack, and then the left-hand side names are assigned using opcodes that take values from the stack again.
For tuple assignments with 2 or 3 items, Python just uses the stack directly:
After the two
LOAD_FASTopcodes (which push a value from a variable onto the stack), the top of stack holds[a, b]. TheROT_TWOopcode swaps the top two positions on the stack so the stack now has[b, a]at the top. The twoSTORE_FASTopcodes then takes those two values and store them in the names on the left-hand side of the assignment. The firstSTORE_FASTpops a value of the top of the stack and puts it intoa, the next pops again, storing the value inb. The rotation is needed because Python guarantees that assignments in a target list on the left-hand side are done from left to right.For a 3-name assignment,
ROT_THREEfollowed byROT_TWOis executed to reverse the top three items on the stack.For longer left-hand-side assignments, an explicit tuple is built:
Here the stack with
[d, c, b, a]is used to build a tuple (in reverse order,BUILD_TUPLEpops from the stack again, pushing the resulting tuple onto the stack), and thenUNPACK_SEQUENCEpops the tuple from the stack again, pushes all elements back from the tuple back onto the stack again for theSTORE_FASToperations.The latter may seem like a wasteful operation, but the right-hand side of an assignment may be something entirely different, a function call that produces a tuple perhaps, so the Python interpreter makes no assumptions and uses the
UNPACK_SEQUENCEopcode always. It does so even for the two and three-name assignment operations, but a later (peephole) optimization step replaces aBUILD_TUPLE/UNPACK_SEQUENCEcombination with 2 or 3 arguments with the aboveROT_TWOandROT_THREEopcodes for efficiency.