Question about exausted iterators

George Sakkis george.sakkis at gmail.com
Wed May 17 17:01:40 EDT 2006


Christophe wrote:

> Is there a good reason why when you try to take an element from an
> already exausted iterator, it throws StopIteration instead of some other
> exception ? I've lost quite some times already because I was using a lot
> of iterators and I forgot that that specific function parameter was one.
>
> Exemple :
>
>  >>> def f(i):
> ...     print list(i)
> ...     print list(i)
> ...
>  >>> f(iter(range(2)))
> [0, 1]
> []

Whether trying to iterate over an exhausted iterator should be treated
differently is appication dependent. In most cases, you don't really
care to distinguish between an iterator that yields no elements and an
iterator that did yield some elements before but it has been exhausted.
If you do care, you can roll your own iterator wrapper:


class ExhaustibleIterator(object):
    def __init__(self, iterable):
        self._next = getattr(iterable, 'next', iter(iterable).next)
        self._exhausted = False

    def next(self):
        if self._exhausted:
            raise ExhaustedIteratorException()
        try: return self._next()
        except StopIteration:
            self._exhausted = True
            raise

    def __iter__(self):
        return self

class ExhaustedIteratorException(Exception):
    pass


And then in your function:
def f(i):
    i = ExhaustibleIterator(i)
    print list(i)
    print list(i)


HTH,
George




More information about the Python-list mailing list