Comportamento estranho do iterador Python [duplicado]

Esta questão já tem uma resposta aqui:

Variáveis ​​locais em funções aninhadas 3 respostas

Eu estava brincando com geradores Python e oitertools módulo e tentei fazer uma versão infinita do Crivo de Eratóstenes. Aqui está o meu 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)

Quando eu testo, eu entendo isso:

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

Mas se eu substituir a reatribuição decandidates com uma função assim:

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)

Eu recebo:

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

Não consigo descobrir porque a primeira versão não funciona. Tanto quanto eu posso dizer, as duas versões devem ser equivalentes. Alguém sabe por que eles não são os mesmos?

questionAnswers(1)

yourAnswerToTheQuestion