[Python-ideas] Generator syntax hooks?

Steven D'Aprano steve at pearwood.info
Fri Aug 11 01:13:36 EDT 2017


On Fri, Aug 11, 2017 at 02:34:53PM +1000, Nick Coghlan wrote:

> This is actually how I came to the conclusion that if we were ever to
> do something like this, the termination condition would need to go
> *before* the filter condition:

What if you want to check the filter condition before the termination 
condition?

I have an iterable of arbitrary objects. I want to ignore anything that 
isn't a string, and halt if the string doesn't start with "A". This is 
easy:


[expr for s in objects if isinstance(s, str) while s.startswith("A")]


Why should we prohibit expressing this, and instead write it as this?

[expr for s in objects while (s.startswith("A")) if isinstance(s, str) else True) if isinstance(s, str)]


Or split into multiple comprehensions?

[expr for s in [obj for obj in objects if isinstance(obj, str)] while s.startswith("A")]


>     (expr for var in seq while loop_cond if filter_cond)
> 
>     <=>
> 
>     for var in seq:
>         if loop_cond:
>             if filter_cond:
>                 yield expr
>         else:
>             break


We can still expand the clauses if they are presented in the opposite 
order:

    (expr for var in seq if filter_cond while loop_cond)

    <=>

    for var in seq:
        if filter_cond:
            if loop_cond:
                yield expr
            else:
                break

There's no need to prohibit that. It is meaningful and useful and just 
because somebody might accidentally fail to exit an infinite loop is no 
reason to ban this.


> This is another good reason why a termination condition would need to
> be checked before the filter condition rather than either after it, or
> only when the filter condition was true.

Why is this a problem that needs solving?

Who is to say that an infinite generator expression isn't exactly what 
the programmer wants? If the halting condition is not true, the 
generator expression will either keep going until the iterator is 
exhausted, or it will be an infinite generator just like the 
unprocessed, unfiltered source iterator. This is not necessarily a 
problem.




-- 
Steve


More information about the Python-ideas mailing list