Python Lambda不能与过滤器一起工作
我试图用流动代码打印所有小于100的素数: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)
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 namen
指向包含新值的新内存地址,但lambda中的var namen
仍然指向原始地址?因此,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'])