python - Filtering another filter object -
i trying generate prime endlessly,by filtering out composite numbers. using list store , test primes makes whole thing slow, tried use generators.
from itertools import count def chk(it,num): 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 hit maximum recursion depth. found ifilter (or filter in python 3). documentation of python standard library:
make iterator filters elements iterable returning predicate true. if predicate none, return items true. equivalent to:
def ifilter(predicate, iterable): # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9 if predicate none: predicate = bool x in iterable: if predicate(x): yield x
so 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 get:
2 3 5 7 11 13 17 ...
what is:
2 3 4 5 6 7 ...
it seems next()
iterate through count()
, not filter. object in list should point object, expected works filter(lambda x: x%n,(.... (filter(lambda x:x%3,filter(lambda x:x%2,count(2))))
. experiment , noticed following characteristic:
filter(lambda x:x%2,filter(lambda x:x%3,count(0))
) #works, filter 2*n , 3*ngenstore = [count(2)]; genstore.append(filter(lambda x:x%2,genstore[-1])); genstore.append (filter(lambda x:x%2,genstore[-1]))
- works, filter 2*n , 3*nnext(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: in genstore[-1]: print(i) #it doesn't work, filtering out 4*n.
questions:
- why doesn't work?
- is feature of python, or made mistakes somewhere?
- is there way fix it?
i think problem stems fact lambdas not evaluated it's 'too late' , prime same of them of them point @ same variable.
you can try add custom filter , use normal function instead of lambda:
def myfilt(f, i, p): 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 avoid problems of lambdas being same
Comments
Post a Comment