On 11 August 2017 at 01:39, Paul Moore <p.f.mo...@gmail.com> wrote:
> On 10 August 2017 at 14:42, Steven D'Aprano <st...@pearwood.info> wrote:
>> I don't think it is confusing. Regardless of the implementation, the
>> meaning of:
>> [expression for x in sequence while condition]
>> should (I believe) be obvious to anyone who already groks comprehension
>> syntax. The mapping to a for-loop is admittedly a tad more complex:
>> result = 
>> for x in sequence:
>> if not condition: break
>> but I'm yet to meet anyone who routinely and regularly reads
>> comprehensions by converting them to for loops like that. And if they
>> did, all they need do is mentally map "while condition" to "if not
>> condition: break" and it should all Just Work™.
> The hard part is the interaction between if and while.
> Consider (expr for var in seq if cond1 while cond2):
> This means:
> for var in seq:
> if cond1:
> if not cond2: break
> yield expr
> Note that unlike all other comprehension clauses (for and if) while
> doesn't introduce a new level of nesting. That's an inconsistency, and
> while it's minor, it would need clarifying (my original draft of this
> email was a mess, because I misinterpreted how if and while would
> interact, precisely over this point).
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:
(expr for var in seq while loop_cond if filter_cond)
for var in seq:
With the clauses in that order, the "while" keyword effectively
operates as "if-else-break" the same way it does in a regular while
loop, and could potentially be introduced as a modifying clause on
regular for loops at the same time.
One of the neat things the latter would allow is to make it even
easier to introduce a diagnostic loop counter into while loops:
for iteration in itertools.count(1) while condition:
rather than having to implement a manually incremented loop counter
the way you do today.
> Also, there's a potential issue
> here - consider
> [expr for var in even_numbers() if is_odd(var) while var < 100]
> This is an infinite loop, even though it has a finite termination
> condition (var < 100), because we only test the termination condition
> if var is odd, which it never will be.
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.
Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia
Python-ideas mailing list
Code of Conduct: http://python.org/psf/codeofconduct/