Filtering another filter object
Question: I am trying to generate prime endlessly,by filtering out composite numbers.
Using list to store and test for all primes makes the whole thing slow, so i
tried to use generators.

    
    
    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))
    

It works quite well, generating primes, until it hit maximum recursion depth.
So I found ifilter (or filter in python 3). From [documentation of python
standard
library](https://docs.python.org/2/library/itertools.html#itertools.ifilter):

> Make an iterator that filters elements from iterable returning only those
> for which the predicate is True. If predicate is None, return the items that
> are true. Equivalent to:
    
    
    def ifilter(predicate, iterable):
        # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
        if predicate is None:
            predicate = bool
        for x in iterable:
            if predicate(x):
                yield x
    

So I get the following:

    
    
    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]))
    

I expected to get:

    
    
    2
    3    
    5
    7
    11
    13
    17
    ...
    

What I get is:

    
    
    2
    3
    4
    5
    6
    7
    ...
    

It seems `next()` only iterate through `count()`, not the filter. Object in
list should point to the object, so I expected it works like `filter(lambda x:
x%n,(.... (filter(lambda x:x%3,filter(lambda x:x%2,count(2))))`. I do some
experiment and noticed the following characteristic:

  1. `filter(lambda x:x%2,filter(lambda x:x%3,count(0))`) #works, filter all 2*n and 3*n
  2. `genStore = [count(2)]; genStore.append(filter(lambda x:x%2,genStore[-1])); genStore.append (filter(lambda x:x%2,genStore[-1]))` \- works, also filter all 2*n and 3*n
  3. `next(filter(lambda x:x%2,filter(lambda x:x%3,count(2))))` \- works, printing out 5

On contrast:

    
    
    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.
    

Questions:

  * Why doesn't it work?
  * Is it a feature of python, or I made mistakes somewhere? 
  * Is there any way to fix it?


Answer: I think your problem stems from the fact that lambdas are not evaluated will
it's 'too late' and then you will get prime be same for all of them as all of
them point at the same variable.

you can try to add custom filter and use normal function instead of 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)
    

this way you avoid the problems of lambdas being all the same

