堆栈filter()调用的奇怪行为

Col*_*ury 5 python filter

所以我从for循环中堆叠的一些过滤器中获得了一些有趣的行为.我将从演示开始:

>>> x = range(100)
>>> x = filter(lambda n: n % 2 == 0, x)
>>> x = filter(lambda n: n % 3 == 0, x)
>>> list(x)
[0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96]
Run Code Online (Sandbox Code Playgroud)

在这里,我们得到预期的输出.我们在过滤器内的过滤器内有一个范围,过滤条件按我们希望的方式堆叠.现在我的问题来了.
我编写了一个函数来计算数字的相对素数.它看起来像这样:

def relative_primes(num):
    '''Returns a list of relative primes, relative to the given number.'''
    if num == 1:
        return []
    elif is_prime(num):
        return list(range(1, num))
    result = range(1, num)
    for factor in prime_factors(num):
        # Why aren't these filters stacking properly?                           
        result = filter(lambda n: n % factor != 0, result)
    return list(result)
Run Code Online (Sandbox Code Playgroud)

无论出于何种原因,过滤器仅应用于从prime_factors()获取的列表中的LAST因子.例:

>>> prime_factors(30)  
[2, 3, 5]  
>>> relative_primes(30)  
[1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24, 26, 27, 28, 29]
Run Code Online (Sandbox Code Playgroud)

我们可以看到没有从列表中删除2或3的倍数.为什么会这样?为什么上面的例子有效,但for循环中的过滤器不起作用?

Ign*_*ams 7

在Python 3.x中,filter()返回生成器而不是列表.因此,仅使用最终值,factor因为所有三个过滤器都使用相同的值factor.您需要稍微修改lambda才能使其正常工作.

result = filter(lambda n, factor=factor: n % factor != 0, result)
Run Code Online (Sandbox Code Playgroud)