# How does swapping of members in tuples (a,b)=(b,a) work internally?

## Question:

``````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.

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:

``````>>> import dis
>>> def foo(a, b):
...     a, b = b, a
...
>>> dis.dis(foo)
6 ROT_TWO
7 STORE_FAST               0 (a)
10 STORE_FAST               1 (b)
16 RETURN_VALUE
``````

After the two `LOAD_FAST` opcodes (which push a value from a variable onto the stack), the top of stack holds `[a, b]`. The `ROT_TWO` opcode swaps the top two positions on the stack so the stack now has `[b, a]` at the top. The two `STORE_FAST` opcodes then takes those two values and store them in the names on the left-hand side of the assignment. The first `STORE_FAST` pops a value of the top of the stack and puts it into `a`, the next pops again, storing the value in `b`. 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_THREE` followed by `ROT_TWO` is executed to reverse the top three items on the stack.

For longer left-hand-side assignments, an explicit tuple is built:

``````>>> def bar(a, b, c, d):
...     d, c, b, a = a, b, c, d
...
>>> dis.dis(bar)
12 BUILD_TUPLE              4
15 UNPACK_SEQUENCE          4
18 STORE_FAST               3 (d)
21 STORE_FAST               2 (c)
24 STORE_FAST               1 (b)
27 STORE_FAST               0 (a)
Here the stack with `[d, c, b, a]` is used to build a tuple (in reverse order, `BUILD_TUPLE` pops from the stack again, pushing the resulting tuple onto the stack), and then `UNPACK_SEQUENCE` pops the tuple from the stack again, pushes all elements back from the tuple back onto the stack again for the `STORE_FAST` operations.
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_SEQUENCE` opcode always. It does so even for the two and three-name assignment operations, but a later (peephole) optimization step replaces a `BUILD_TUPLE` / `UNPACK_SEQUENCE` combination with 2 or 3 arguments with the above `ROT_TWO` and `ROT_THREE` opcodes for efficiency.