Я думаю, что проблема в том, что вы полагаетесь на локальные переменные, а созданные вами генераторы (используя filter()
) ссылаются на локальные переменные, которые перезаписываются, когда генератор продолжает итерацию.
Если вместо этого вы используете локальную функцию, она работает нормально:
def sieve():
def selector(iterator, d):
for x in iterator:
if x % d != 0:
yield x
picker = itertools.count(2)
while True:
# take the next available number
prime = next(picker)
yield prime
# filter from the generator its multiples
picker = selector(picker, prime)
Попытка list(itertools.islice(sieve(), 10))
показывает:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Но мне действительно нужно указать, что это чисто образовательное решение, чтобы показать, как все работает. Я бы не предложил использовать это решение для какого-либо производительного кода. Он создает большое количество генераторов внутри, которые освобождаются, только когда вы опускаете дескриптор родительского генератора. Вероятно, это пустая трата ресурсов, и вы можете создать бесконечное количество простых чисел, не создавая бесконечное количество генераторов.