I am trying to code a lazy version of Sieve of Eratosthenes in Python 3.2. Here's the code:
import itertools
def primes():
candidates = itertools.count(2)
while True:
prime = next(candidates)
candidates = (i for i in candidates if i % prime)
yield prime
However, when I iterate over primes(), I only get consecutive numbers. E.g.,
print(list(itertools.islice(primes(),0,10)))
prints the list
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
To my surprise, the following tiny modification of primes() makes it work:
def primes():
candidates = itertools.count(2)
while True:
prime = next(candidates)
candidates = (i for i in candidates if i % prime)
next(itertools.tee(candidates)[1]) ########### NEW LINE
yield prime
I am guessing I am missing something about the scope of the parameters of the generator
candidates = (i for i in candidates if i % prime)
but I cannot see how to fix the code without adding this random-looking new line. Does anybody know what I am doing wrong? Thanks.