我在python中编写了一些代码来获取一些素数:
N = (x for x in range(2,100))
while i<50:
n = next(N)
print(n)
N = filter(lambda x:x % n > 0,N)
i = i+1
我认为它应该打印素数2,3,5,7,11 .... 但结果却是2,3,4,5,6,7 ......就像过滤器没有用。 我想也许这是lambda的问题,它没有成功提供n的值,所以我只是将我的代码更改为:
def fil(n):
return lambda x:x % n > 0
N = (x for x in range(2,100))
i = 0
while i<50:
n = next(N)
print(n)
N = filter(fil(n),N)
i = i+1
有效。
但我仍然怀疑,所以我写了这些:
N = (x for x in range(2,100))
i = 0
while i<50:
n = next(N)
print(n)
N = filter(lambda x:x % n == 0,N)
i = i+1
刚刚更改了lambda x:x%n&gt; 0到lambda x:x%n == 0。其他部分是相同的。这次它有效,给我2 ^ x:2,4,8,16,32 ......过滤器可以工作。
这让我很困惑。如何解释/理解这个?
答案 0 :(得分:2)
filter
是懒惰的,因此在请求下一个数字之前不会应用过滤器。当您不使用闭包范围作为谓词时,最终会使用n
的实时值,因此您可以有效地测试每个数字是否可以被前一个数字整除(即,何时测试4,每个filter
包装是重新检查它是否可以被3,5整除,可以通过4次反复检查可分性等等),这绝不是这种情况(我强烈怀疑你的输出从未包括在内) 1
但是,因为你原来的genexpr甚至不会产生1)。
对原始代码的最简单修复是在函数定义时使用默认参数绑定n
,而不是在函数体中引用它,该函数在调用时在嵌套作用域中查找它,获得实时价值。你所要做的就是改变:
N = filter(lambda x: x % n > 0, N)
为:
N = filter(lambda x, n=n: x % n > 0, N)