How to unget a line when reading from a file/stream iterator/generator?
Arnaud Delobelle
arnodel at googlemail.com
Mon Apr 28 14:42:50 EDT 2008
python at bdurham.com writes:
> Is there an elegant way to unget a line when reading from a file/stream
> iterator/generator?
>
> By "unget" I mean a way to push back a line into the source stream and
> backtrack the iterator/generator one step?
>
> The only alternative I can see is to put my line reading in a while-True
> loop (vs. a for-loop) that manually calls my file/stream
> iterator/generator's .next() method while manually handling the
> StopIteration exception. Doesn't sound too elegant.
>
> Is there a Pythonic design pattern/best practice that I can apply here?
It seems to me that the answer depends on what you do with your
unget'ed line (i.e. there is no included general purpose 'unget'
replacement). If you provided some (pseudo-)code, someone might be
able to find an elegant way to perform the task without the need to
push back an element into an iterator.
As a last resort, you could always wrap your iterator into a some
'Backtrackable' class.
class Backtrackable(object):
def __init__(self, iterator):
self.iterator = iter(iterator)
self._back = False
self._last = None
def __iter__(self):
return self
def next(self):
if self._back:
next = self._last
else:
self._last = next = self.iterator.next()
self._back = False
return next
def back(self):
if self._back:
raise('Cannot backtrack twice')
self._back = True
>>> b = Backtrackable([1,2,3])
>>> b.next()
1
>>> b.next()
2
>>> b.back()
>>> b.next()
2
>>> b.next()
3
More information about the Python-list
mailing list