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 >> result.append(expression) >> >> 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: if loop_cond: if filter_cond: yield expr else: break 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: while condition: ... could become: 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. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/