[Python-ideas] Return expressions

MRAB python at mrabarnett.plus.com
Thu Nov 20 13:54:36 CET 2014


On 2014-11-20 10:01, Nick Coghlan wrote:
> This idea occurred to me in context of PEP 479 and the "or stop()" hack
> for generator expressions. I'm not a big enough fan of the idea to
> pursue it myself, but if anyone is bothered by the prospect of PEP 479
> taking the "or stop()" technique away, this may be worth pursuing further.
>
> As a reminder of how the hack works, the following generator:
>
>  >>> def takewhile(iterable, pred):
> ...     for x in iter(iterable):
> ...         if not pred(x):
> ...             return
> ...         yield x
> ...
>  >>> list(takewhile(range(10), (lambda x: x < 5)))
> [0, 1, 2, 3, 4]
>
> Can currently be converted to a generator expression with the aid of a
> helper function:
>
>  >>> def stop():
> ...     raise StopIteration
> ...
>  >>> list(x for x in range(10) if x < 5 or stop())
> [0, 1, 2, 3, 4]
>
> Under PEP 479, that will raise RuntimeError instead. If return was an
> expression rather than a statement (ala the yield statement ->
> expression conversion in PEP 342), then the following would be
> functionally equivalent to the current "or stop()" trick:
>
>  >>> list(x for x in range(10) if x < 5 or return)
> [0, 1, 2, 3, 4]
>
> This is emphatically *not* executable pseudocode - it only makes sense
> in terms of the translation to the corresponding full generator function
> definition. However, the translation remains exact in terms of the
> normal semantics of the "return" keyword, unlike various other proposals
> to use the "while" keyword to provide comparable functionality.
>
> For comprehensions, the meaning of a bare return would likely need to be
> tweaked slightly to be the same as reaching the end of the frame:
> returning the object being constructed by the comprehension, rather than
> None.
>
>  >>> [x for x in range(10) if x < 5 or return]
> [0, 1, 2, 3, 4]
>  >>> {x for x in range(10) if x < 5 or return}
> {0, 1, 2, 3, 4}
>  >>> {x:x for x in range(10) if x < 5 or return}
> {0:0, 1:1, 2:2, 3:3, 4:4}
>
I'd prefer 'while' instead:

 >>> [x for x in range(10) while x < 5]
[0, 1, 2, 3, 4]
 >>> {x for x in range(10) while x < 5}
{0, 1, 2, 3, 4}
 >>> {x:x for x in range(10) while x < 5}
{0:0, 1:1, 2:2, 3:3, 4:4}



More information about the Python-ideas mailing list