[Python-ideas] Allowing breaks in generator expressions by overloading the while keyword

Andrew Barnert abarnert at yahoo.com
Sat Feb 22 00:02:35 CET 2014


First, given how often this comes up: Is it worth reopening PEP 3142 to at least add the additional considerations raised over the past 5 years, and maybe have Nick or someone write a better rejection message than a link to Guido's "I didn't know there was a PEP for that. I hereby reject it."?

From: Greg Ewing <greg.ewing at canterbury.ac.nz>

Sent: Friday, February 21, 2014 2:33 PM


> Nick Coghlan wrote:
>>      isprime = all(n % p for p in takewhile((: ? ** 2 < n), primes_seen))
> 
> -1, this is far too cryptic and ugly to have a place in Python.
> 
> I'd be +0 on adding a while clause to for-loops, in
> *both* comprehension and statement forms, so that the
> above could be written
> 
>    isprime = all(n % p for p in primes_seen while p ** 2 < n)
> 
> Adding a corresponding clause to the for-statement
> would allow the semantic definition of list comprehensions
> in terms of the statement expansion to be preserved.

As I mentioned somewhere else, all of the languages that have the equivalent of while in comprehensions do it this way: the while is not a comprehension clause in its own, following the usual nesting rules like for and if, it's a modifier to the for clause. (In those languages, that's _also_ how if in comprehensions works, but there's no reason Python couldn't have a hybrid design, where while works on the Clojure/Racket model and if on the Miranda/Haskell model.) So:

    (n % p for p in primes_seen while p ** 2 < n if p != 2)

… does not map to the nonsensical:

    for p in primes_seen:
        while p ** 2 < n:
            if p != 2:
                yield n % p

… but to the sensible (and now legal, under the proposal):

    for p in primes_seen while p ** 2 < n:
        if p != 2:
            yield n % p

> However, this all hinges on whether there is enough

> use for the feature to be worth adding. I'm yet to
> be convinced of that.


I think an off-hand comment Nick made the last time around is what convinced me we probably don't need this (and inspired the start of my blog post).

Just as an if clause is a syntactic way of writing filter, a while clause is a syntactic way of writing takewhile. If takewhile isn't even common enough to move from itertools to builtins, is it really common enough to move from a function to special syntax?


More information about the Python-ideas mailing list