[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