On 10 August 2017 at 00:54, Nick Coghlan <ncogh...@gmail.com> wrote: > Yeah, if we ever did add something like this, I suspect a translation > using takewhile would potentially be easier for at least some users to > understand than the one to a break condition: > > {x for x in itertools.count(0) if 1000 <= x while x < 1000000} > > <=> > > x = set() > for x in itertools.count(0): > if 1000 <= x: > set.add(x) > # If you've never used the loop-and-a-half idiom, it's > # not obvious why "while <expr>" means "if not <expr>: break" > if not x < 1000000: > break > > is roughly > > {x for x in itertools.takewhile(itertools.count(0), lambda x: x < > 1000000) if 1000 <= x} > > <=> > > x = set() > for x in takewhile(itertools.count(0), lambda x: x < 1000000): > if 1000 <= x: > set.add(x)
Ugh, this discrepancy is worse than I thought, since the translation with that clause order is actually wrong (Terry mentioned this by pointing out that the proposed syntactic translation implemented "do...while" ordering). The takewhile example is also wrong, since it has the arguments in the wrong order. Fixing both of those issues gives the comparison: {x for x in itertools.count(0) while x < 1000000 if 1000 <= x} <=> x = set() for x in itertools.count(0): # If you've never used the loop-and-a-half idiom, it's # not obvious why "while <expr>" means "if <expr>: <loop body> else: break" if x < 1000000: if 1000 <= x: set.add(x) else: break is roughly: {x for x in itertools.takewhile(lambda x: x < 1000000, itertools.count(0)) if 1000 <= x} <=> x = set() for x in takewhile(lambda x: x < 1000000, itertools.count(0)): if 1000 <= x: set.add(x) And I think that gets me back to pretty much where I was the last time this came up: a while clause in comprehensions really only makes sense in combination with a while clause on for loops, where: for x in itertools.count(0) while x < 1000000: ... was roughly equivalent to: for x in itertools.count(0): if x < 1000000: ... else: <loop else clause, if any, still runs here> break (such that there's only one loop from the point of view of break/continue/else, but the loop may terminate based on either exhaustion of the underlying iterator *or* some specific condition becoming false) While I do think such a clause would be more readable for more people than the dropwhile/takewhile equivalents (especially when the latter end up needing to use lambda expressions), I'm still dubious that these cases come up often enough to justify the addition of a for-while loop as a composite construct (the old "dropwhile and takewhile aren't even common enough to justify being builtins, why should they jump all the way to syntactic support?" question applies). 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/