Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iterate infinite generator until condition is met

I'm having a little trouble understanding generators in python. Lets say I have the following simple generator:

def test_gen():
    yield 1
    yield 2
    yield 5
    yield 8
    yield 12

That will just yield some numbers. Lets say I want to keep printing values from the generator until the value is more than 10. My first attempt was just

gen = test_gen()
for i in gen:
    while i > 10:
        print(i)

But this just prints 1 forever. I found that doing

gen = test_gen()
for i in gen:
    if i > 10:
        print(i)

works as expected because it just iterates through each value in the generator until StopIteration is raised. I then ran into the problem of an infinite generator such as this one that generates prime numbers:

def prime_gen():
    D = dict()
    n = 2
    while True:
        if n not in D:
            yield n
            D[n*n] = [n]
        else:
            for p in D[n]:
                D.setdefault(p + n, []).append(p)
            del D[n]
        n += 1

Then if I do something like

primes = prime_gen()
for p in primes:
    if p < 100:
        print(p)

then it will print everything up to p, but then get hung up. I think it's getting hung up because it's trying to check every value that primes generates, which going on forever. What is the correct way to iterate through an infinite generator until a condition is met like this? The only way I have found is doing

primes = prime_gen()
for p in primes:
    if p < 100:
        print(p)
    else:
        break

but I feel like there's a more pythonic way of doing it.

like image 927
TheStrangeQuark Avatar asked Dec 13 '22 17:12

TheStrangeQuark


1 Answers

itertools.takewhile()

for i in itertools.takewhile(lambda x: x < 100, primes):
  print(i)
like image 111
Ignacio Vazquez-Abrams Avatar answered Dec 28 '22 06:12

Ignacio Vazquez-Abrams