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

Andrew Barnert abarnert at yahoo.com
Thu Jun 27 13:49:53 CEST 2013


From: Nick Coghlan <ncoghlan at gmail.com>

Sent: Thursday, June 27, 2013 1:43 AM


> Someone was asking earlier why I thought PEP 403 was at all relevant
> to these discussions. It's because it makes it easy to define a one
> shot generator function to precisely control the iterable in a
> comprehension. If we assume a world where itertools.takewhile doesn't
> exist, you could write an equivalent inline:
> 
>     @in x = [transform(value) for value in my_takewhile(pred, iterable)]
>     def my_takewhile(pred, itr):
>         for x in itr:
>             if not pred(x):
>                 break
>             yield x


I'm still not sure how it's relevant here.

Obviously takewhile already exists in the stdlib, and if I wanted stop I'd probably want it frequently enough to define it and reuse it. So, for the current discussion, are you just suggesting using it to break up an overly-verbose or -complex takewhile solution, as an answer to "Yeah, I know about takewhile, but it's too verbose or complex so I don't want to use it"?

If so, I don't think it answers that. If someone wants this:

    x = [value for value in iterable if value > 0 while value < 10]

… and rejects this:

    x = [value for value in takewhile(lambda x: x < 10, iterable) if value > 0]

… I don't think they'd be happier with this:

    @in x = [value for value in takewhile(under10, iterable) if value > 0]
    def under10(value):
        return value < 10

And as someone who _wouldn't_ reject the takewhile, if I want to break it up, I'd be happier going in the opposite direction:

    iterable_to_10 = takewhile(lambda value: value < 10, iterable)
    x = [value for value in iterable_to_10 if value > 0]

That puts it as a sequence of simple transformations to an iterable, rather than a bunch of simple functions plugged into different places in one big expression. (Although admittedly my stupid toy example, with its total of 1 transformations or functions, isn't the best demonstration of that…)


Where your idea would really be useful is, exactly, as you say, "… to get access to full statement syntax, but we only use it in this one place". I don't think the kinds of things people are envisioning putting in while clauses need statement syntax. The only reason statement syntax even really came up is the idea of break and/or a more-statement-like if as an alternative to while. Having a real function wouldn't help with break, because you're not allowed to break across function boundaries.


In fact, I think what people really want is the opposite: to write an expression, not a function. That's a big part of the appeal of using comprehensions over map and filter: if you don't already have a ready-made function, no problem (and no lambdas or partials), just use a comprehension and write the expression in-place. People want a similar answer to make takewhile at least as unnecessary as map and filter.



More information about the Python-ideas mailing list