Python 筛选另一个筛选对象

Python 筛选另一个筛选对象,python,recursion,filter,Python,Recursion,Filter,我正试图通过过滤掉复合数,无休止地生成素数。使用列表存储和测试所有素数会使整个过程变得缓慢,所以我尝试使用生成器 from itertools import count def chk(it,num): for i in it: if i%num: yield(i) genStore = [count(2)] primeStore = [] while 1: prime = next(genStore[-1]) primeStore

我正试图通过过滤掉复合数,无休止地生成素数。使用列表存储和测试所有素数会使整个过程变得缓慢,所以我尝试使用生成器

from itertools import count
def chk(it,num):
    for i in it:
        if i%num:
            yield(i)
genStore = [count(2)]
primeStore = []
while 1:
    prime = next(genStore[-1])
    primeStore.append(prime)
    genStore.append(chk(genStore[-1],num))
它工作得很好,生成素数,直到达到最大递归深度。 所以我找到了ifilter(或python 3中的filter)。 发件人:

制作一个迭代器,从iterable中过滤元素,只返回谓词为True的元素。如果谓词为None,则返回为true的项。相当于:

因此,我得到以下信息:

from itertools import count
genStore = [count(2)]
primeStore = []
while 1:
    prime = next(genStore[-1])
    primeStore.append(prime)
    genStore.append(filter(lambda x:x%num,genStore[-1]))
我希望得到:

2
3    
5
7
11
13
17
...
我得到的是:

2
3
4
5
6
7
...
似乎
next()
只遍历
count()
,而不是过滤器。列表中的对象应该指向该对象,所以我希望它的工作方式类似于
过滤器(lambda x:x%n,(..(过滤器(lambda x:x%3,过滤器(lambda x:x%2,计数(2))))
。我做了一些实验,注意到以下特性:

  • 过滤器(λx:x%2,过滤器(λx:x%3,计数(0))
    )#工作,过滤所有2*n和3*n
  • genStore=[count(2)];genStore.append(过滤器(lambda x:x%2,genStore[-1]);genStore.append(过滤器(lambda x:x%2,genStore[-1]))
    -工作,同时过滤所有2*n和3*n
  • next(过滤器(lambda x:x%2,过滤器(lambda x:x%3,计数(2)))
    -works,打印出5
  • 相比之下:

    from itertools import count
    genStore = [count(2)]
    primeStore = []
    while 1:
        prime = next(genStore[-1])
        print(prime)
        primeStore.append(prime)
        genStore.append(filter(lambda x:x%prime,genStore[-1]))
        if len(genStore) == 3:
            for i in genStore[-1]:
                print(i)
    #It doesn't work, only filtering out 4*n.
    
    问题:

    • 为什么不起作用
    • 这是python的一个特性,还是我在某个地方犯了错误
    • 有没有办法解决这个问题

    我认为你的问题源于这样一个事实:lambda没有被评估,这“太晚了”,然后你会得到它们的质数相同,因为它们都指向同一个变量

    您可以尝试添加自定义筛选器并使用普通函数而不是lambda:

    def myfilt(f, i, p):
        for n in i:
            print("gen:", n, i)
            if f(n, p):
                yield n
    
    def byprime(x, p):
        if x % p:
            print("pri:", x, p)
            return True
    
    f = myfilt(byprime, genStore[-1], prime)
    

    这样就避免了lambdas完全相同的问题

    当素数变大时,它仍然会产生最大的递归错误。我使用ifilter的原因是为了避免这个错误。我认为不管你使用什么,它都会发生,因为在某个点上素数的密度会下降到非常低的水平,所以这是这个解决方案的局限性,你无法做到使用惰性过滤时,请远离
    def myfilt(f, i, p):
        for n in i:
            print("gen:", n, i)
            if f(n, p):
                yield n
    
    def byprime(x, p):
        if x % p:
            print("pri:", x, p)
            return True
    
    f = myfilt(byprime, genStore[-1], prime)