On Wed, Jan 11, 2017 at 10:07 AM, Ian Kelly <ian.g.ke...@gmail.com> wrote: > On Wed, Jan 11, 2017 at 8:51 AM, Peng Yu <pengyu...@gmail.com> wrote: >> Hi, peekable from more-itertools only allow peeking an iterator. But >> sometimes, one may want to take a look at an element, manipulate it, >> then put it back to the iterator. Is there a class in python that can >> help do this? > > Not that I'm aware of, but maybe this recipe will help. > > > from collections import deque > > class PushIterator: > > def __init__(self, iterable, push=()): > self._iter = iter(iterable) > self._pushed = deque(push) > self._stopped = False > > def push(self, item): > if self._stopped: > raise RuntimeError('Cannot push onto exhausted iterator') > self._pushed.append(item) > > def __iter__(self): > return self > > def __next__(self): > if self._pushed: > return self._pushed.pop() > try: > return next(self._iter) > except StopIteration: > self._stopped = True > raise
And in case it's not obvious, adding a peek method to this is pretty simple: from collections import deque class PushIterator: def __init__(self, iterable, push=()): self._iter = iter(iterable) self._pushed = deque(push) self._stopped = False def peek(self): item = next(self) self.push(item) return item def push(self, item): if self._stopped: raise RuntimeError('Cannot push onto exhausted iterator') self._pushed.append(item) def __iter__(self): return self def __next__(self): if self._pushed: return self._pushed.pop() try: return next(self._iter) except StopIteration: self._stopped = True raise -- https://mail.python.org/mailman/listinfo/python-list