Unpack python tuple with [ ]'s

Viewed 709

I know the canonical way to unpack a tuple is like this

a, b, c = (1, 2, 3)
# or
(a,b,c) = (1, 2, 3)

but noticed that you can unpack a tuple like this

[a, b, c] = (1, 2, 3)

Does the second method incur any extra cost due to some sort of cast or list construction? Is there a way to inspect how the python interpreter is dealing with this akin to looking at the assembly from a compiler?

3 Answers

No, those are all exactly equivalent. One way to look at this empirically is to use the dis dissasembler:

>>> import dis
>>> dis.dis("a, b, c = (1, 2, 3)")
  1           0 LOAD_CONST               0 ((1, 2, 3))
              2 UNPACK_SEQUENCE          3
              4 STORE_NAME               0 (a)
              6 STORE_NAME               1 (b)
              8 STORE_NAME               2 (c)
             10 LOAD_CONST               1 (None)
             12 RETURN_VALUE
>>> dis.dis("(a, b, c) = (1, 2, 3)")
  1           0 LOAD_CONST               0 ((1, 2, 3))
              2 UNPACK_SEQUENCE          3
              4 STORE_NAME               0 (a)
              6 STORE_NAME               1 (b)
              8 STORE_NAME               2 (c)
             10 LOAD_CONST               1 (None)
             12 RETURN_VALUE
>>> dis.dis("[a, b, c] = (1, 2, 3)")
  1           0 LOAD_CONST               0 ((1, 2, 3))
              2 UNPACK_SEQUENCE          3
              4 STORE_NAME               0 (a)
              6 STORE_NAME               1 (b)
              8 STORE_NAME               2 (c)
             10 LOAD_CONST               1 (None)
             12 RETURN_VALUE
>>>

From the formal language specification, this is detailed here. This is part of the "target list", A relevant quote:

Assignment of an object to a target list, optionally enclosed in parentheses or square brackets, is recursively defined as follows....

Using godbolt and selecting Python as the language then entering the three lines of code, you can see they all have the same bytecode:

  1           0 LOAD_CONST               5 ((1, 2, 3))
              2 UNPACK_SEQUENCE          3
              4 STORE_NAME               0 (a)
              6 STORE_NAME               1 (b)
              8 STORE_NAME               2 (c)

  2          10 LOAD_CONST               6 ((1, 2, 3))
             12 UNPACK_SEQUENCE          3
             14 STORE_NAME               0 (a)
             16 STORE_NAME               1 (b)
             18 STORE_NAME               2 (c)

  3          20 LOAD_CONST               7 ((1, 2, 3))
             22 UNPACK_SEQUENCE          3
             24 STORE_NAME               0 (a)
             26 STORE_NAME               1 (b)
             28 STORE_NAME               2 (c)

So, they are the same, just different syntaxes.

I have checked the execution time and number of cycles using Linux perf tools. All 3 programs are showing the same execution time, so I think there are not any extra costs.

Related