13

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?

ShadowRanger
  • 108,619
  • 9
  • 124
  • 184
George Sovetov
  • 3,923
  • 4
  • 26
  • 54
  • 1
    That's just `*` and `**` unpacking. Are you familiar with that? – TigerhawkT3 May 02 '16 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. – George Sovetov May 02 '16 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.) – TigerhawkT3 May 02 '16 at 11:13

1 Answers1

21

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}
Community
  • 1
  • 1
kennytm
  • 469,458
  • 94
  • 1,022
  • 977