首页 > 解决方案 > 迭代器的意外行为

问题描述

我尝试使用迭代器来实现 Eratosthenes 的筛子(因为我想更多地使用 python 进行函数式编程)。可悲的是,发生了一些意想不到的行为。您可以在此视频中看到它:https ://imgur.com/gallery/XfXFw4a

这是我的代码:

def sieve_primes(stop=10):
    L = (x for x in range(2, stop+1))
    while True:
        prime = next(L)
        L = filter(lambda x: x % prime != 0 or x == prime, L)
        #L, M = itertools.tee(L)
        #print(list(M))
        yield prime

当两个注释行未注释时,它可以工作(吐出具有所需素数的迭代器对象)。否则,它只会遍历每个数字。

我期待着您的回答:) 谢谢!

标签: pythonpython-3.xfunctional-programmingiteratorsieve-of-eratosthenes

解决方案


prime在 lambda 中使用变量,这是您从封闭范围继承的引用。当您的代码评估 lambda 时,它将使用在继承引用的范围内绑定到该引用的任何值。当您不使用tee和评估列表时,所有 lambda 函数都是相同的,并且对prime.

tee工作原理是将结果存储在一个列表中,并在您稍后再次询问时从该列表中将它们提供给您,因此对于它的每个值prime实际上将过滤器应用于来自的所有值L

prime您可以通过在 的范围内绑定来解决此问题,方法lambda是将其作为具有默认值的参数传递。这将该值保存为函数对象的一部分,prime然后引用是对该存储值的本地引用。


推荐阅读