[Python-Dev] Any grammar experts?

Guido van Rossum guido at python.org
Sun Jan 25 23:59:42 CET 2015


On Sun, Jan 25, 2015 at 7:32 AM, Georg Brandl <g.brandl at gmx.net> wrote:

> On 01/25/2015 04:08 PM, Antoine Pitrou wrote:
> > On Sat, 24 Jan 2015 21:10:51 -0500
> > Neil Girdhar <mistersheik at gmail.com> wrote:
> >> To finish PEP 448, I need to update the grammar for syntax such as
> >>
> >> {**x for x in it}
> >
> > Is this seriously allowed by the PEP? What does it mean exactly?
>
> It appears to go a bit far.  Especially since you also would have to allow
>
> {*x for x in it}
>
> which is a set comprehension, while the other is a dict comprehension :)
>

That distinction doesn't bother me -- you might as well claim it's
confusing that f(*x) passes positional args from x while f(**x) passes
keyword args.

And the varargs set comprehension is similar to the varargs list
comprehension:

[*x for x in it]

If `it` were a list of three items, this would be the same as

[*it[0], *it[1], *it[2]]

so the original is a flattening of `it`: [*it[0], *it[1], ...]. (The type
of `it` is wider than list of lists -- it could be an iterable of
iterables. But the thing is still a flattening.)

The set flattening follows from a direct analogy. And `it` doesn't have to
be a set of sets, it still  just needs to be an iterable of iterables --
it's only the flattened result that's turned into a set.

The dict comprehension follows from there -- the input must be an iterable
of iterables of (key, value) pairs.

I like the example from the PEP, a dict combining globals() and locals():

    {**dictionary for dictionary in (globals(), locals())}

This could be written as

    {**globals(), **locals()}

but the general case (a variable number of dicts to combine) requires the
comprehension.

The PEP also supports generator expressions that are flattenings, and again
that follows directly from analogy.

Interestingly, the non-dict versions can all be written today using a
double-nested comprehension, e.g. {**x for x in it} can be written as:

    {x for x in xs for xs in it}

But it's not so straightforward for dict comprehensions -- you'd have to
switch to calling dict():

    dict(x for x in xs for xs in it)

-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20150125/f2316d03/attachment.html>


More information about the Python-Dev mailing list