Reputation: 782
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
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
ina, *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