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

Guido van Rossum guido at python.org
Sat Mar 15 23:21:12 CET 2008


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.  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)

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

*yield x

instead of

yield *x

???

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
>



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list