Seltsames Verhalten des Python-Iterators [duplizieren]

Diese Frage hat hier bereits eine Antwort:

Lokale Variablen in verschachtelten Funktionen 3 Antworten

Ich habe mit Python-Generatoren und dem gespieltitertools Modul und versuchte eine unendliche Version des Sieve of Eratosthenes zu machen. Hier ist mein Code:

from itertools import count, ifilter, islice

def sieve_broken():
    candidates = count(start=2)
    while True:
        prime = next(candidates)
        yield prime
        candidates = ifilter(lambda n: n % prime, candidates)

Wenn ich es ausprobiere, erhalte ich Folgendes:

>>> print list(islice(sieve_broken(), 10))
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Aber wenn ich die Neuzuordnung voncandidates mit einer Funktion wie folgt:

def sieve_fixed():
    def exclude_multiples(factor, numbers):
        return ifilter(lambda n: n % factor, numbers)

    candidates = count(start=2)
    while True:
        prime = next(candidates)
        yield prime
        candidates = exclude_multiples(prime, candidates)

Ich bekomme:

>>> print list(islice(sieve_fixed(), 10))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Ich kann nicht herausfinden, warum die erste Version nicht funktioniert. Soweit ich das beurteilen kann, sollten die beiden Versionen gleichwertig sein. Weiß jemand, warum sie nicht gleich sind?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage