[Python-ideas] Generator syntax hooks?
Steven D'Aprano
steve at pearwood.info
Thu Aug 10 09:42:33 EDT 2017
On Wed, Aug 09, 2017 at 01:23:28PM -0700, Chris Barker wrote:
> I can't recall the use case(s) at the moment, but I have definitely wanted
> a way to break out of a comprehension -- and not always with infinite
> iterators.
>
> After all, we have "break" in both for and while loops, so clearly there is
> the use case...
Indeed :-)
> If someone comes up with a clean and not confusing (and general purpose)
> syntax, I think it would be very useful.
We used to be able to (ab)use StopIteration to do this:
def Break():
raise StopIteration
# generator expressions only, not list comprehensions
result = (expression for x in sequence if condition or Break())
but I believe that loophole has been closed in 3.6.
Comprehensions in Clojure have this feature:
http://clojuredocs.org/clojure_core/clojure.core/for
Clojure uses "when" where Python uses "if", giving:
;; :when continues through the collection even if some have the
;; condition evaluate to false, like filter
user=> (for [x (range 3 33 2) :when (prime? x)]
x)
(3 5 7 11 13 17 19 23 29 31)
;; :while stops at the first collection element that evaluates to
;; false, like take-while
user=> (for [x (range 3 33 2) :while (prime? x)]
x)
(3 5 7)
Translating into Python:
[x for x in range(3, 33, 2) if is_prime(x)]
[x for x in range(3, 33, 2) while is_prime(x)] # hypothetical syntax
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™.
--
Steve
More information about the Python-ideas
mailing list