Python3的过滤器,带有lambda函数和生成器

时间:2015-11-30 18:28:23

标签: python-3.x filter lambda generator itertools

请考虑使用这个Python 3代码,使用无限制的eratosthenes筛网生成素数:

import itertools
def primes():
    numbers = itertools.count(2)
    while True:
        prime = next(numbers)
        yield prime
        numbers = filter(prime.__rmod__,numbers)

prime_gen = primes()
next(prime_gen)
# Prints 2
next(prime_gen)
# Prints 3
next(prime_gen)
# Prints 5
next(prime_gen)
# Prints 7

到目前为止一切顺利。现在,让我们用一个执行相同操作的lambda替换prime.__rmod__函数:

import itertools
def primes():
    numbers = itertools.count(2)
    while True:
        prime = next(numbers)
        yield prime
        numbers = filter(lambda n: n % prime,numbers)

prime_gen = primes()
next(prime_gen)
# Prints 2
next(prime_gen)
# Prints 3
next(prime_gen)
# Prints 4
next(prime_gen)
# Prints 5

为什么lambda函数不能使用过滤器? lambda函数的范围有变化吗?

1 个答案:

答案 0 :(得分:0)

作为R Nar评论,这是由于lambda函数的范围。因为prime对于lambda函数是全局的,所以当prime尝试执行其工作时,filter的相同值将用于每个lambda中。解决方案是为每个lambda创建一个闭包,以便在创建它们时记住prime的值:

filter(lambda n, prime=prime: n % prime,numbers)