Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does unpacking give a list instead of a tuple in Python?

This is really strange to me, because by default I thought unpacking gives tuples.

In my case I want to use the prefix keys for caching, so a tuple is preferred.

# The r.h.s is a tuple, equivalent to (True, True, 100)
*prefix, seed = ml_logger.get_parameters("Args.attn", "Args.memory_gate", "Args.seed")
assert type(prefix) is list

But I thought unpacking would return a tuple instead.

Here is the relevant PEP: https://www.python.org/dev/peps/pep-3132/

-- Update --

Given the comment and answers bellow, specifically I was expecting the unpacking to give a tuple because in function arguments a spread arg is always a tuple instead of a list.

As Jason pointed out, during unpacking one would not be able to know the length of the result ahead of time, so implementation-wise the catch-all has to start as a list for dynamic appends. Converting it to a list is a waste of effort the majority of the time.

Semantically, I would prefer to have a tuple for consistency.

like image 636
episodeyang Avatar asked Apr 25 '20 16:04

episodeyang


People also ask

Why would you use a list instead of a tuple?

The major difference is that a list is mutable, but a tuple isn't. So, we use a list when we want to contain similar items, but use a tuple when we know what information goes into it.

Can you unpack a tuple in Python?

In python tuples can be unpacked using a function in function tuple is passed and in function values are unpacked into normal variable.

How does tuple unpacking work in Python?

Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list ) of variables in a single assignment statement. As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator, * .

Can you unpack a list like a tuple?

You can also unpack a nested tuple or list. If you want to expand the inner element, enclose the variable with () or [] .


1 Answers

This issue was mentioned in that PEP (PEP 3132):

After a short discussion on the python-3000 list [1], the PEP was accepted by Guido in its current form. Possible changes discussed were: [...]

  • Try to give the starred target the same type as the source iterable, for example, b in a, *b = 'hello' would be assigned the string 'ello'. This may seem nice, but is impossible to get right consistently with all iterables.

  • Make the starred target a tuple instead of a list. This would be consistent with a function's *args, but make further processing of the result harder.

But as you can see, these features currently are not implemented:

In [1]: a, *b, c = 'Hello!'
In [2]: print(a, b, c)
H ['e', 'l', 'l', 'o'] !

Maybe, mutable lists are more appropriate for this type of unpacking.

like image 189
trsvchn Avatar answered Sep 26 '22 21:09

trsvchn