Comportamiento extraño de iterador de Python [duplicado]

Esta pregunta ya tiene una respuesta aquí:

Variables locales en funciones anidadas 3 respuestas

Estaba jugando con los generadores de Python y elitertools Módulo y trató de hacer una versión infinita del Tamiz de Eratóstenes. Aquí está mi código:

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)

Cuando lo pruebo, me sale esto:

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

Pero si sustituyo la reasignación decandidates con una función así:

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)

Yo obtengo:

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

No puedo entender por qué la primera versión no funciona. Por lo que puedo decir, las dos versiones deben ser equivalentes. ¿Alguien sabe por qué no son lo mismo?

Respuestas a la pregunta(1)

Su respuesta a la pregunta