# [Python-3000] Using *a for packing in lists and other places

Thomas Wouters thomas at python.org
Sun Mar 16 00:01:38 CET 2008

```On Sat, Mar 15, 2008 at 3:21 PM, Guido van Rossum <guido at python.org> wrote:

> This post does point out an inconistency in Thomas's patch:
>
> def f():
>  yield 1, 2, 3
>
> Yields a single three-tuple.
>
> But
>
> def f():
>  yield *[1, 2], 3
>
> Yields three separate values.

Uhm, what? It doesn't, and it shouldn't, and I'm not sure what makes you
think it does.

>>> def f():
...     yield *[1, 2], 3
...
>>> list(f())
[(1, 2, 3)]

The comma makes the argument to 'yield' a single item (a tuple) and the '*'
is part of the item in the tuple. In other words, the * binds more tightly
than the comma (which is not something I changed; the parser already worked
this way and it's necessary for '*a, b, c = ..' to even work.  'yield *[1,
2], 3' is parsed as 'yield (*[1, 2], 3)', not 'yield *([1, 2], 3)'. What you
suggest (three separate values) requires 'yield *(*[1, 2], 3)'.

>>> def f1():
...     yield (*[1, 2], 3)
...
>>> list(f1())
[(1, 2, 3)]

>>> def f2():
...     yield *([1, 2], 3)
...
>>> list(f2())
[[1, 2], 3]

>>> def f3():
...     yield *(*[1, 2], 3)
...
>>> list(f3())
[1, 2, 3]

I think this is inconsistent, since
>
> (1, 2, 3)
>
> and
>
> (*[1, 2], 3)
>
> are equivalent, and so are
>
> yield 1, 2, 3
>
> and
>
> yield (1, 2, 3)

Yes, they are indeed all equivalent :-)

>
>
> I'm not sure how to solve this except by adopting a different syntax
> for the multiple-yield. Perhaps
>
> *yield x
>
>
> yield *x
>
> ???

If there really were an inconsistency here, I would certainly not suggest
fixing it that way, yuuueghh.

>
> On Sat, Mar 15, 2008 at 4:58 PM, Terry Reedy <tjreedy at udel.edu> wrote:
> >
> >  "Guido van Rossum" <guido at python.org> wrote in message
> >  news:ca471dc20803150915l27750346g8655f596f5035c69 at mail.gmail.com...
> >
> > | Thomas Wouters suggests some new syntax:
> >
> >  I see this as two suggestions:
> >  1. Complete the extension of the validity of *expression syntax from
> >  function call/definition to expression/assignment.
> >  2. Give *expression a related meaning in yield statements.
> >
> >
> >  |
> >  | http://bugs.python.org/issue2292
> >  |
> >  | >>> a, b, *c = range(5)
> >  |
> >  | >>> *a, b, c = a, b, *c
> >  | >>> a, b, c
> >  | ([0, 1, 2], 3, 4)
> >  | >>> [ *a, b, c ]
> >  | [0, 1, 2, 3, 4]
> >
> >  I understand 'f(*a)' to mean 'execute the expression as if the items of
> >  iterable a has been written literally in the code (with 'as if'
> >  optimizations allowed for special cases).  The above follow the same
> rule.
> >  +1
> >  A tutorial written for Py3 without regard to history should then
> introduce
> >  *expressions in examples like the above first, and only later the usage
> for
> >  functions, as if things had been this way all along.
> >
> >
> >  | >>> L = [ a, (3, 4), {5}, {6: None}, (i for i in range(7, 10)) ]
> >  | >>> [ *item for item in L ]
> >  | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> >
> >  Since above will become equivalent to list(gen_exp), I see this as
> being
> >  tied to yield *exp.
> >
> >
> >  | Also, yielding everything from an iterator:
> >  |
> >  | >>> def flatten(iterables):
> >  | ...     for it in iterables:
> >  | ...         yield *it
> >
> >  Following the general rule above for *exp, that would be the same as
> yield
> >  tuple(it).  But that is nearly useless, whereas the the implicit inner
> for
> >  loop meaning is quite useful, with, perhaps, a speedup over an explicit
> >  inner loop.  Since yield is already pretty magical,a bit more might not
> >  hurt.
> >
> >  But, ... what do you do with
> >     yield *a,b,c # a,b,c as above?
> >  Yield a 5-tuple?  That would clash badly with 'yield *a' not yielding a
> >  3-tuple.
> >  Raise an exception?  That establishes/requires a new grammatical
> >  category -- yield_expression.  But I would see this as preferable to
> the
> >  clash.
> >
> >  Terry Jan Reedy
> >
> >
> >
> >
> >  _______________________________________________
> >  Python-3000 mailing list
> >  Python-3000 at python.org
> >  http://mail.python.org/mailman/listinfo/python-3000
> >  Unsubscribe:
> http://mail.python.org/mailman/options/python-3000/guido%40python.org
> >
>
>
>
> --
> )
> _______________________________________________
> Python-3000 mailing list
> Python-3000 at python.org
> http://mail.python.org/mailman/listinfo/python-3000
> Unsubscribe:
> http://mail.python.org/mailman/options/python-3000/thomas%40python.org
>

--
Thomas Wouters <thomas at python.org>

Hi! I'm a .signature virus! copy me into your .signature file to help me