<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Jan 25, 2015 at 7:32 AM, Georg Brandl <span dir="ltr"><<a href="mailto:g.brandl@gmx.net" target="_blank">g.brandl@gmx.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On 01/25/2015 04:08 PM, Antoine Pitrou wrote:<br>
> On Sat, 24 Jan 2015 21:10:51 -0500<br>
> Neil Girdhar <<a href="mailto:mistersheik@gmail.com">mistersheik@gmail.com</a>> wrote:<br>
>> To finish PEP 448, I need to update the grammar for syntax such as<br>
>><br>
>> {**x for x in it}<br>
><br>
> Is this seriously allowed by the PEP? What does it mean exactly?<br>
<br>
</span>It appears to go a bit far.  Especially since you also would have to allow<br>
<br>
{*x for x in it}<br>
<br>
which is a set comprehension, while the other is a dict comprehension :)<span class=""></span><br></blockquote></div><br></div><div class="gmail_extra">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.<br><br>And the varargs set comprehension is similar to the varargs list comprehension:<br><br></div><div class="gmail_extra">[*x for x in it]<br><br></div><div class="gmail_extra">If `it` were a list of three items, this would be the same as<br><br></div><div class="gmail_extra">[*it[0], *it[1], *it[2]]<br><br>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.)<br><br>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.<br><br>The dict comprehension follows from there -- the input must be an iterable of iterables of (key, value) pairs.<br><br></div><div class="gmail_extra">I like the example from the PEP, a dict combining globals() and locals():<br><br>    {**dictionary for dictionary in (globals(), locals())}<br><br></div><div class="gmail_extra">This could be written as<br><br></div><div class="gmail_extra">    {**globals(), **locals()}<br><br></div><div class="gmail_extra">but the general case (a variable number of dicts to combine) requires the comprehension.<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">The PEP also supports generator expressions that are flattenings, and again that follows directly from analogy.<br><br></div><div class="gmail_extra">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:<br><br></div><div class="gmail_extra">    {x for x in xs for xs in it}<br><br></div><div class="gmail_extra">But it's not so straightforward for dict comprehensions -- you'd have to switch to calling dict():<br><br></div><div class="gmail_extra">    dict(x for x in xs for xs in it)<br clear="all"></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>
</div></div>