2

What is the result of unpacking? I thought the unpacking result is a first class citizen that I can use as an object.

>>> print(*range(5))
0 1 2 3 4

However, apparently it cannot be evaluated to be an object and I cannot get its type. So, I wonder what is the unpacking operation generating?

>>> *range(5)
  File "<stdin>", line 1
SyntaxError: can't use starred expression here

>>> type(*range(5))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type() takes 1 or 3 arguments

>>> *values, = 1,2,3

>>> values
[1, 2, 3]
>>> *values
  File "<stdin>", line 1
SyntaxError: can't use starred expression here
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
mon
  • 18,789
  • 22
  • 112
  • 205
  • 5
    Why do you assume there is a result? Syntax does not necessarily have to be an expression that can be evaluated in all contexts. – timgeb Jan 15 '21 at 06:57
  • *"I thought the unpacking result is a first class citizen that I can use as an object."* Why did you think this? Is there a language reference which says so? – kaya3 Jan 15 '21 at 06:57
  • 1
    Check [this](https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists), [this](https://www.python.org/dev/peps/pep-3102/) and [this](https://www.python.org/dev/peps/pep-3132/). – Olvin Roght Jan 15 '21 at 06:59
  • @timgeb, I think it is what I have not understood yet. "Syntax does not necessarily have to be an expression". Currently I think "syntax is to be evaluated to generate a result" and I am assuming "result is an object". – mon Jan 15 '21 at 07:06
  • @timgeb, For ```print(*range(5))```, it generates ```0,1,2,3,4```, so I thought at somewhere ```*range(5)``` has been ```evaluated``` to generate those integer '0' or '1', etc. Appreciate if you could explain how Python interpreter generates those integers from ```*``` syntax. – mon Jan 15 '21 at 07:17
  • @mon: nice question. For me, the strangest thing is that `x = *range(5),` will evaluate to a tuple, but `x = *range(5)` is a SyntaxError. Somewhere in Python Developer's Guide should be clear answer to your question. – Qiu Jan 15 '21 at 07:20
  • 2
    Unpacking **is** the act of taking a collection and using its element as *different function arguments*. This means that it exists only in the context of a function call. Assignment unpacking is a similar thing that uses the same syntax in a different context `start,*middle,end = range(5)` this does some form of pattern matching to assign `0` to `start`, `[1,2,3]` to `middle` and `4` to `end`. – Bakuriu Jan 15 '21 at 07:39
  • 1
    @Qiu, it's not strange at all. Trailing coma creates tuple, so you just unpacking range into a tuple. `x = *range(5),` is the same as `x = tuple(range(5))` – Olvin Roght Jan 15 '21 at 07:39
  • 4
    `*range(5)` isn't a thing, but `func(*)` is. This is maybe as succinctly as it can be put. The `*` is part of the function call syntax, not the other way around. (And for completeness, certain other constructs supports it as well, like `[*]`.) – deceze Jan 15 '21 at 07:44
  • 1
    @mon There are many sequences of characters that are correct syntax but do not return a result, for example `def foo(): pass`. You cannot put it on the right hand side of an assignment. – timgeb Jan 15 '21 at 08:51
  • There is probably a better duplicate to use. Unpacking is quite different from a `*` parameter in a function definition, syntactic similarities aside. – chepner Jan 16 '21 at 13:51

0 Answers0