关于过滤器和lambda的问题

时间:2017-03-08 03:27:16

标签: python python-3.x

我在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 ......过滤器可以工作。

这让我很困惑。如何解释/理解这个?

1 个答案:

答案 0 :(得分:2)

Python 3上的

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)