11

How does it work under the hood? I don't understand the reason for the errors below:

>>> def f():
...     yield 1,2
...     yield 3,4
...
>>> *f()
  File "<stdin>", line 1
    *f()
    ^
SyntaxError: invalid syntax
>>> zip(*f())
[(1, 3), (2, 4)]
>>> zip(f())
[((1, 2),), ((3, 4),)]
>>> *args = *f()
File "<stdin>", line 1
  *args = *f()
    ^
SyntaxError: invalid syntax
jamylak
  • 128,818
  • 30
  • 231
  • 230
Rusty Rob
  • 16,489
  • 8
  • 100
  • 116
  • Are you looking for ['itertools.consume'](http://docs.python.org/library/itertools.html#recipes)? – Katriel Jun 10 '12 at 10:14
  • 1
    Sorry, I was more wanting to know how *Generator works, and where you can use it. – Rusty Rob Jun 10 '12 at 10:58
  • The problem has **nothing to do with** the fact that a generator is used. All of these issues are equally reproducible if `f` returns a list, or if a list is used directly instead. Instead, the problem is that there *has to be something to unpack into*. `*args = ...` doesn't work, but [in 3.x](https://peps.python.org/pep-3132/) `*args, = ...` (note the trailing comma) will put everything into a list called `args`. – Karl Knechtel May 07 '23 at 23:44

3 Answers3

14

The *iterable syntax is only supported in an argument list of a function call (and in function definitions).

In Python 3.x, you can also use it on the left-hand side of an assignment, like this:

[*args] = [1, 2, 3]

Edit: Note that there are plans to support the remaining generalisations.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
5

Running this in Python 3 gives a more descriptive error message.

>>> *f()
SyntaxError: can use starred expression only as assignment target
jamylak
  • 128,818
  • 30
  • 231
  • 230
1

The two errors are showing the same thing: you can't use * on the left-hand side of an expression.

I'm not sure what you're expecting to happen in those cases, but it's not valid.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895