20

I'm playing now with Python 3.5 interpreter and found very interesting behavior:

>>> (1,2,3,"a",*("oi", "oi")*3)
(1, 2, 3, 'a', 'oi', 'oi', 'oi', 'oi', 'oi', 'oi')
>>> [1,2,3,"a",*range(10)]
[1, 2, 3, 'a', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ('aw','aw',*range(10),*(x**2 for x in range(10)))
('aw', 'aw', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
>>> {"trali":"vali", **dict(q=1,p=2)}
{'q': 1, 'p': 2, 'trali': 'vali'}
>>> {"a",1,11,*range(5)}
{0, 1, 2, 3, 4, 11, 'a'}

I have never seen that neither in documentation and examples nor in any source code despite several years of my Python experience. And I found it very useful.

And it seems logical for me from point of view of Python grammar. Function arguments and tuple may be parsed with same or similar states.

Is it documented behavior? Where is it documented?

Which versions of Python have this functionality?

3
  • 1
    That's just * and ** unpacking. Are you familiar with that? Commented May 2, 2016 at 11:10
  • @TigerhawkT3 No. But now I know that it's called unpacking. I used it many times in function calls but never used in this context. Commented May 2, 2016 at 11:13
  • And I'm guessing you're using 3.5, which has extended functionality for that. It doesn't work on my 3.4 setup on this machine and I only have 3.5 on my other PC. (Never mind, I notice now that you are using 3.5.) Commented May 2, 2016 at 11:13

1 Answer 1

32

This is PEP-448: Additional Unpacking Generalizations, which is new in Python 3.5.

The relevant change-log is in https://docs.python.org/3/whatsnew/3.5.html#pep-448-additional-unpacking-generalizations:

PEP 448 extends the allowed uses of the * iterable unpacking operator and ** dictionary unpacking operator. It is now possible to use an arbitrary number of unpackings in function calls:

>>>

>>> print(*[1], *[2], 3, *[4, 5])
1 2 3 4 5

>>> def fn(a, b, c, d):
...     print(a, b, c, d)
...

>>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})
1 2 3 4

Similarly, tuple, list, set, and dictionary displays allow multiple unpackings:

>>>

>>> *range(4), 4
(0, 1, 2, 3, 4)

>>> [*range(4), 4]
[0, 1, 2, 3, 4]

>>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7}

>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}

Not the answer you're looking for? Browse other questions tagged or ask your own question.