genexp surprise (wart?)

Paul Rubin http
Fri May 26 00:21:44 EDT 2006


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)

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)

Oh well.



More information about the Python-list mailing list