The Python language (especially 3.x) allows very general unpacking of iterables, a simple example of which is
a, *rest = 1, 2, 3
Over the years, this unpacking has been gradually generalized (see e.g. PEP 3132 and PEP 448), allowing it to be used in more and more circumstances. As so, I was surprised to discover that the following is invalid syntax in Python 3.6 (and remains so in Python 3.7):
def f(): rest = [2, 3] return 1, *rest # Invalid
I can make it work by encapsulating the returned tuple in parentheses like so:
def f(): rest = [2, 3] return (1, *rest) # Valid
The fact that I use this in a return
statement seems to be important, as
t = 1, *rest
is indeed legal and results in the same with and without parentheses.
Have this case simply been forgotten by the Python developers, or are there any reason why this case is invalid syntax?
This breaks an important contract I thought I had with the Python language. Consider the following (also valid) solution:
def f(): rest = [2, 3] t = 1, *rest return t
Normally when I have code like this, I consider t
to be a temporary name, which I ought to be able to get rid of simply be replacing t
in the bottom line with its definition. In this case though, this leads to the invalid code
def f(): rest = [2, 3] return 1, *rest
It's of course no big deal to have to place parentheses around the return value, but usually additional parentheses are only needed to distinguish between several possible outcomes (grouping). Here this is not the case, as leaving out the parentheses does not produce some other unwanted behavior, but rather no behavior at all.
Since Python 3.8 (see item 7 on this list), the generalized syntax discussed above is now valid.
In python tuples can be unpacked using a function in function tuple is passed and in function values are unpacked into normal variable.
Unpacking Tuples When we put tuples on both sides of an assignment operator, a tuple unpacking operation takes place. The values on the right are assigned to the variables on the left according to their relative position in each tuple . As you can see in the above example, a will be 1 , b will be 2 , and c will be 3 .
A Python function can return any object such as a tuple. To return a tuple, first create the tuple object within the function body, assign it to a variable your_tuple , and return it to the caller of the function using the keyword operation “ return your_tuple “.
Unpack a Tuple in a for Loop in PythonThe number of variables on the left side or before the equals sign should equal the length of the tuple or the list. For example, if a tuple has 5 elements, then the code to unpack it would be as follows. We can use the same syntax to unpack values within a for loop.
I suspect this is an accident, based on the comments from this commit for Python 3.2.
That commit enabled the assignment expression to take a testlist_star_expr
production (what allows the unparenthesized unpacking), but left the return statement taking a testlist
production. I suspect the commit just missed this (and possibly other locations, but I'm focusing on the return_stmt
production for now).
I went ahead and modified the Python Grammar/Grammar file to allow this. All of the tests continue to pass, including those in the test_grammar.py
file (but this doesn't seem terribly exhaustive).
If you're curious, this is the change I made. Feel free to clone or download my fork.
UPDATE: I've submitted a bpo issue and a pull request for the return (and yield) unpacking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With