Python Lambda不能与过滤器一起工作

Python Lambda不能与过滤器一起工作,python,python-3.x,lambda,Python,Python 3.x,Lambda,我试图用流动代码打印所有小于100的素数: def _odd_iter(): n=1 while True: n=n+2 yield n def _not_divisible(n): return lambda x: x % n > 0 def primes(): yield 2 it = _odd_iter() while True: n=next(it)

我试图用流动代码打印所有小于100的素数:

def _odd_iter():
    n=1
    while True:
        n=n+2
        yield n

def _not_divisible(n):
    return lambda x: x % n > 0    

def primes():
    yield 2
    it = _odd_iter()
    while True:
            n=next(it)
            yield n
            it = filter(_not_divisible(n),it)

for n in primes():
    if n<100:
        print(n)
    else:
        break
结果表明,过滤器没有掉落任何东西


为什么它不能与lambda一起工作?

问题是lambda中使用的
n
总是引用本地值。如果周围环境中的
n
发生变化,它也会在lambda*中发生变化。如果要捕获当前值,可以改用以下方法:

it = filter(lambda x, n=n: x % n > 0, it)

*如果您将上下文视为一个字典,其中存储和查找局部变量,并且始终保持不变,那么可能更容易理解。以这种方式显式编写的
primes()
函数如下所示:

def primes():
    ctx = {}
    yield 2
    ctx['it'] = _odd_iter()
    while True:
            ctx['n'] = next(ctx['it'])
            yield ctx['n']
            ctx['it'] = filter(lambda x: x % ctx['n'] > 0, ctx['it'])

现在应该很清楚,当
ctx
中的值发生变化时,lambda中也会检测到这些变化。基本上,如果没有
ctx
dict,同样的情况也会发生,这就是经常导致误解的原因。

您在使用python时遇到了捕获规则。请看@AnilRedshift,他希望有人能找到一个很好的现有问题。谢谢!:)很抱歉,我没有理解这句话的意思:如果
n
发生变化,它也会在lambda内发生变化。这是否意味着,尽管函数
primes
中的var name
n
指向包含新值的新内存地址,但lambda中的var name
n
仍然指向原始地址?因此,lambda中的
n
没有改变。@TJM-试图更好地解释它,希望能有所帮助
def primes():
    ctx = {}
    yield 2
    ctx['it'] = _odd_iter()
    while True:
            ctx['n'] = next(ctx['it'])
            yield ctx['n']
            ctx['it'] = filter(lambda x: x % ctx['n'] > 0, ctx['it'])