episodeyang
episodeyang

Reputation: 782

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.

Upvotes: 9

Views: 1256

Answers (1)

trsvchn
trsvchn

Reputation: 8981

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.

Upvotes: 7

Related Questions