With Python 2.2+, you can make generators that return unbounded output. By creating a "wrapper" generator that runs the first generator, you can restrict its output to some defined subset.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def genWhile(g, condition):
"""
run generator g while 'condition' is true.
Condition is a partial expression such as "< 10"
to be evaluated with g.next() as the left side
"""
while 1:
next = g.next()
if eval("next " + condition):
yield next
else:
return
def genEven():
x = 0
while 1:
x += 2
yield x
def main():
print [x for x in genWhile(genEven(), "< 12")]
|
The generator "genEven" above, generates all positive even numbers. To see the positive even numbers < 12, it would be tempting to write something like:
[x for x in genEven() if x < 12]
But this does not work. Instead, we can use the wrapper "genWhile" to get a similar effect:
[x for x in genWhile(genEven(), "< 12")]
fix. The "return" statement in the code above should be indented so as to be inside the else:
Use the two argument form of iter. You can use the two-argument form of iter() to get some of the same effect.
So, this:
gives the same result as this:
Of course, genWhile is more flexible, as it understands predicates rather than just a simple sentinel.