Paul Rubin wrote: > I tried to code the Sieve of Erastosthenes with generators: > > def sieve_all(n = 100): > # yield all primes up to n > stream = iter(xrange(2, n)) > while True: > p = stream.next() > yield p > # filter out all multiples of p from stream > stream = (q for q in stream if q%p != 0) > > # print primes up to 100 > print list(sieve_all(100)) > > but it didn't work. I had to replace > > stream = (q for q in stream if q%p != 0) > > with > > def s1(p): > return (q for q in stream if q%p != 0) > stream = s1(p) > > or alternatively > > stream = (lambda p,stream: \ > (q for q in stream if q%p != 0)) (p, stream)
You do realize that you're creating a new level of generator nesting with each iteration of the while loop, right? You will quickly hit the maximum recursion limit. Try generating the first 1000 primes. > I had thought that genexps worked like that automatically, i.e. the > stuff inside the genexp was in its own scope. If it's not real > obvious what's happening instead, that's a sign that the current > behavior is a wart. (The problem is that p in my first genexp comes > from the outer scope, and changes as the sieve iterates through the > stream) I don't see how it's a wart. p is accessed (i.e., not set) by the genexp. Consistent with the function scoping rules in... http://www.python.org/doc/faq/programming/#what-are-the-rules-for-local-and-global-variables-in-python ...Python treats p in the genexp as a non-local variable. --Ben -- http://mail.python.org/mailman/listinfo/python-list