1

The usual way to swap values in a list is to use a temporary variable.

temp = l[i]
l[i] = l[j]
l[j] = temp

But in python you can do this:

l[i], l[j] = l[j], l[i]

How does this second method work? Is it the exact same process? Does it use less / more memory?

1

2 Answers 2

4
import dis


def swap_using_temp(a, b):
    temp = a
    a = b
    b = temp


def swap_using_unpacking(a, b):
    a, b = b, a

swap_using_unpacking does not require extra memory.

Explanation: If you disassemble the code using dis module of both the function described then you will see that in swap_using_unpacking there is a bytecode instruction ROT_TWO which swaps the 2 topmost elements of the stack(which don't require a third variable hence no extra memory is consumed).



dis.dis(swap_using_unpacking)

 11           0 LOAD_FAST                1 (b)
              2 LOAD_FAST                0 (a)
              4 ROT_TWO
              6 STORE_FAST               0 (a)
              8 STORE_FAST               1 (b)
             10 LOAD_CONST               0 (None)
             12 RETURN_VALUE

dis.dis(swap_using_temp)

  5           0 LOAD_FAST                0 (a)
              2 STORE_FAST               2 (temp)

  6           4 LOAD_FAST                1 (b)
              6 STORE_FAST               0 (a)

  7           8 LOAD_FAST                2 (temp)
             10 STORE_FAST               1 (b)
             12 LOAD_CONST               0 (None)
             14 RETURN_VALUE
Sign up to request clarification or add additional context in comments.

1 Comment

Great. I had wrong thought that when we use , between two o more expressions , Python will pack them into a (here temporary) tuple. Maybe this isn't the case here because on the left hand side there is exactly these two a and b. Is that the reason there is no BUILD_TUPLE in instructions?
2

You are asking the wrong question here. You are not using assembly language but Python, so you should not worry for some extra bytes. What really matters in Python is readability.

Anyway, both versions should be internally implemented more or less the same way, except that the first one creates an additional identifier. It is explicitely named temp so provided you do not use it in that scope, it brings no real problem.

If you use a linting environment that warns you for possible problems (what you should do...) you must be aware that reusing a variable name that hides the same name in an outer scope, while perfectly correct on a language point of view will light some warning on. But as you should not use a temp identifier outside a local scope (readability...) it should not be a problem either.

So it is more of a matter of taste. If you or your team mates often use other languages that do not allow multiple assignments the first way will be more natural. If you mainly use Python, the second way is IMHO more pythonic because it avoids adding an unnecessary identifier in the local scope. But as I have already said, nothing more that a matter of taste...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.