Iterator that supports pushback
Asked Answered
R

2

5

I'm looking for a why to convert a regular iterator into one that supports pushing items back into it. E.g.

item = next(my_iterator)
if went_too_far(item):
    my_iterator.pushback(item)
    break;

This is similar, but not identical to, an iterator that supports peek; with the latter, the above would look more like this:

if went_too_far(my_iterator.peek()):
    break
else:
    item = next(my_iterator)
Rictus answered 27/2, 2016 at 0:21 Comment(0)
R
8
class PushbackWrapper(object):

    def __init__(self, iterator):
        self.__dict__['_iterator'] = iterator
        self.__dict__['_pushed'] = []

    def next(self):
        if len(self._pushed):
            return self._pushed.pop()
        else:
            return self._iterator.next()

    def pushback(self, item):
        self._pushed.append(item)

    def __getattr__(self, attr):
        return getattr(self._iterator, attr)

    def __setattr__(self, attr, value):
        return setattr(self._iterator, attr, value)

To use it:

pushback_enabled_iterator = PushbackWrapper(original_iterator)

item = next(pushback_enabled_iterator)
if went_too_far(item):
    pushback_enabled_iterator.pushback(item)
    break;
Rictus answered 27/2, 2016 at 0:23 Comment(0)
S
0

Similar idea for Python3

from typing import Iterable


class PushbackIterator:
    def __init__(self, it: Iterable):
        self._it = iter(it)
        self._pushed = False

    def __iter__(self):
        return self

    def __next__(self):
        while True:
            if self._pushed:
                self._pushed = False
                return self._last_val
            else:
                i = next(self._it)
                self._last_val = i
                return i

    def pushback(self):
        self._pushed = True


a = [1, 2, 3, 4, 5]
it = PushbackIterator(a)

for i in it:
    if i == 2:
        # gone too far
        it.pushback()
        break
    print(i)

print("---")

for i in it:
    print(i)

Output

1
---
2
3
4
5
Selection answered 13/7, 2024 at 20:8 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.