[Python-ideas] look ahead iterators

Arnaud Delobelle arno at marooned.org.uk
Wed Jul 25 10:29:39 CEST 2007


Hi,

Several people have felt the need to be able to 'peek ahead' for the next
value of an iterator without actually retrieving it.  I have, and I have a
'peekable' class that I use to wrap around iterators when I need this
feature:

>>> it = iter('python')
>>> it = peekable(it)
>>> it.peek(), it.peek(), it.next(), it.peek(), it.next(), it.next()
('p', 'p', 'p', 'y', 'y', 't')
>>>

There is an example of implementation at:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/304373

A wrapper works fine but a lot of built-in iterators such as
listiterators, tupleiterators, dictionary-***iterators could provide a
peek() method natively, which would be much more efficient and would not
necessitate any buffering. (e.g. in the case of a listiterator, peek()
would be the same as next() but without incrementing the it_index counter)

My idea is the following :

* iterators such as the ones listed above, where providing a peek() method
does not require any buffering or extra bookkeeping, implement this method
natively.

* for the other ones, no peek() method but a user can still wrap them as
in the example above.

* to provide a common interface, define a peekable class like this:

class peekable(object):
    def __new__(cls, iterator):
        # if the iterator is already 'peekable', return it
        # otherwise wrap it
        if hasattr(iterator, 'peek'):
            return iterator
        else:
            return object.__new__(cls)
    def __init__(self, iterator):
        ...
    def __iter__(self):
        return self
    def next(self):
	...
    def peek(self):
        ...

This means that an iterator would have the option of providing a peek()
method, but wouldn't have to.  However all iterators could be made
peekable by writing

   it = peekable(it)

-- 
Arnaud





More information about the Python-ideas mailing list