Boolean value of generators

Steve Howell showell30 at yahoo.com
Thu Oct 14 22:35:59 EDT 2010


On Oct 14, 7:08 pm, Paul Rubin <no.em... at nospam.invalid> wrote:
> Steven D'Aprano <st... at REMOVE-THIS-cybersource.com.au> writes:
> > (4) Expensive generators. The beauty of generators is that they produce
> > values on demand. Making all generators cache their first value means
> > that you pay that cost even if you end up never needing the first value.
>
> You wouldn't generate the cached value ahead of time.  You'd just
> remember the last generated value so that you could use it again.
> Sort of like getc/ungetc.
>
> An intermediate measure might be to have a stdlib wrapper that added
> caching like this to an arbitrary generator.  I've written such things a
> few times in various clumsy ways.  Having the caching available in the C
> code would eliminate a bunch of indirection.

Is there an idiomatic way in Python to wrap a generator with a getc/
ungetc mechanism?

I know Paul is not alone in having written such things himself in
various clumsy ways.

This is my own clumsy attempt, but it seems like there should be a
simpler way to achieve what I'm doing.

    def abc():
        yield 'a'
        yield 'b'
        yield 'c'

    for letter in abc():
        print letter

    class Wrap:
        def __init__(self, g):
            self.g = g
            self.use_cached = False

        def get(self):
            if self.use_cached:
                self.use_cached = False
                return self.value
            self.value = self.g.next()
            return self.value

        def unget(self):
            if self.use_cached:
                raise Exception('only one unget allowed')
            self.use_cached = True


    w = Wrap(abc())
    print w.get()
    w.unget()
    print w.get()
    print w.get()
    for letter in w.g:
        print letter




More information about the Python-list mailing list