[Python-ideas] Is this PEP-able? for X in ListY while conditionZ:

Nick Coghlan ncoghlan at gmail.com
Thu Jun 27 14:19:19 CEST 2013


On 27 June 2013 21:28, Andrew Barnert <abarnert at yahoo.com> wrote:
> From: Oscar Benjamin <oscar.j.benjamin at gmail.com>
>
> Sent: Thursday, June 27, 2013 3:16 AM
>
>
>> On 27 June 2013 08:28, Andrew Barnert <abarnert at yahoo.com> wrote:
>>>  Let me try to gather together all of the possibilities that have been
>>> discussed
>>>  in this and the two previous threads, plus a couple of obvious ones
>>> nobody's
>>>  mentioned.
>>
>> You've missed out having "else return" in comprehensions.
>
> For simplicity, I was just dealing with the "break" solutions, not "continue" and "return" (and "raise" or anything else anyone might want). I should have said that, but I didn't; sorry. So, this goes under case 8.
>
> But it's worth noting that return adds additional mental load on top of break. Comprehensions aren't functions, either conceptually or practically, but it will force you to think of them as functions and carry that cognitive dissonance around as you read them. Comprehensions _are_ loops, so break doesn't have that problem.

FWIW, while I actually agree with you that "else return" doesn't fit
because people *think* of comprehensions and generator as loops rather
than as nested functions, they *are* defined as following the scoping
rules of a nested function and CPython actually implements them that
way:

>>> from dis import dis
>>> dis("[x for x in (1, 2, 3)]")
  1           0 LOAD_CONST               0 (<code object <listcomp> at
0x7f45710efd00, file "<dis>", line 1>)
              3 LOAD_CONST               1 ('<listcomp>')
              6 MAKE_FUNCTION            0
              9 LOAD_CONST               5 ((1, 2, 3))
             12 GET_ITER
             13 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             16 RETURN_VALUE

This is one of the things we cleaned up in Python 3 in order to stop
leaking the iteration variable for comprehensions into the surrounding
scope - we tried a few other options, but ultimately declaring them to
be implicit nested functions proved to be the simplest approach.

If you're willing, I'm actually thinking this may be one of those
discussions that's worth summarising in a PEP, even if it's just to
immediately mark it Rejected. Similar to PEP 315 and a few other PEPs,
it can help to have a document that clearly spells out the objective
(which I think you summarised nicely as "trying to find a syntactic
replacement for itertools.takewhile, just as comprehensions replaced
many uses of map and filter"), even if no acceptable solution has been
found.

That phrasing of the objective also highlights a counter argument I
hadn't considered before: if we don't consider takewhile a common
enough use case to make it a builtin, why on *earth* are we even
discussing the possibility of giving it dedicated syntax?

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list