[Python-3000] Iterators for dict keys, values, and items == annoying :)

Guido van Rossum guido at python.org
Fri Mar 24 02:27:48 CET 2006


On 3/23/06, Ian Bicking <ianb at colorstudy.com> wrote:
> Empty iterator or iterator that produced no items -- from the outside
> it's the same use case.

I see it as an education issue. Because we have generators, the
iterator protocol can't be extended to support a test for emptiness --
that's just not something that generators can be expected to support.
So yes, there's confusion, but there's no way to remove the confusion,
no matter how many times you repeat the usability issues. If we extend
the iterator protocol with a mandatory emptiness test API, that
excludes generators from being considered iterators, and the API
design question you have to ask is whether you want to support
generators.

If you find the 'empty' flag pattern too ugly, you can always write a
helper class that takes an iterator and returns an object that
represents the same iterator, but sometimes buffers one element. But
the buffering violates the coroutine-ish properties of generators, so
it should not be the only (or even the default) way to access
generators.

Here's a sample wrapper (untested):

class IteratorWrapper(object):
    def __init__(self, it):
        self.it = it
        self.buffer = None
        self.buffered = False
        self.exhausted = False
    def __iter__(self):
        return self
    def next(self):
        if self.buffered:
            value = self.buffer
            self.buffered = False
            self.buffer = None
            return value
        if self.exhausted:
            raise StopIteration()
        try:
            return self.it.next()
        except StopIteration:
            self.exhausted = True
            raise
    def __nonzero__(self):
        if self.buffered:
            return True
        if self.exhausted:
            return False
        try:
            self.buffer = self.it.next()
        except StopIteration:
            self.exhausted = True
            return False
        self.buffered = True
        return True

--
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list