【问题标题】:Weird behavior of Python iterator [duplicate]Python迭代器的奇怪行为[重复]
【发布时间】:2013-11-17 02:59:13
【问题描述】:

我正在使用 Python 生成器和 itertools 模块,并尝试制作无限版本的埃拉托色尼筛。这是我的代码:

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)

当我测试它时,我得到了这个:

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

但如果我用这样的函数替换candidates 的重新分配:

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)

我明白了:

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

我无法弄清楚为什么第一个版本不起作用。据我所知,这两个版本应该是等价的。有谁知道他们为什么不一样?

【问题讨论】:

    标签: python iterator


    【解决方案1】:

    您已成为a very common pitfall when using closures in Python 的牺牲品:闭包带有它们的作用域,并且您不断替换同一作用域中的值。

    candidates = ifilter(lambda n, prime=prime: n % prime, candidates)
    

    【讨论】:

    • 我不确定我是否理解......我在哪里定义一个返回函数的函数?
    • @user1475412:您没有返回它,但无论如何,ifilter() 的第一个参数是一个。
    猜你喜欢
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    相关资源
    最近更新 更多