genexp surprise (wart?)

Paul Du Bois paul.dubois at gmail.com
Fri May 26 01:51:11 EDT 2006


The generator is in its own scope. For proof, try accessing q outside
the generator.

There are two possibilities. The first is that you don't know what
closures are and are complaining that python has them. That would be
amusingly ironic, but I'm guessing you do know (if you don't, google
"make_adder" and be enlightened)

The second is that you don't like the late-binding behavior of
generator expressions. PEP 289 has this to say:

> After much discussion, it was decided that the first (outermost)
> for-expression should be evaluated immediately and that the remaining
> expressions be evaluated when the generator is executed.

and:

> After exploring many possibilities, a consensus emerged that [...] [for]
> more complex applications, full generator definitions are always superior
> in terms of being obvious about scope, lifetime, and binding

And as an illustration of that last point, consider:

def sieve_all(n = 100):
    # generate all primes up to n

    def filter_multiples(input, m):
        for q in input:
            if q % m != 0:
                yield q

    stream = iter(xrange(2, n))
    while True:
        p = stream.next()
        yield p
        # this is now a redundant comment.
        # filter out all multiples of p from stream
        stream = filter_multiples(stream, p)


p




More information about the Python-list mailing list