How to unget a line when reading from a file/stream iterator/generator?
Duncan Booth
duncan.booth at invalid.invalid
Tue Apr 29 05:23:33 EDT 2008
George Sakkis <george.sakkis at gmail.com> wrote:
> On Apr 28, 10:10 pm, pyt... at bdurham.com wrote:
>> George,
>>
>> > Is there an elegant way to unget a line when reading from a
>> > file/stream
> iterator/generator?
>>
>> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/502304
>>
>> That's exactly what I was looking for!
>>
>> For those following this thread, the above recipe creates a generic
>> object that wraps any iterator with an 'unget' ("push") capability.
>> Clean and elegant!
>>
>> Thank you,
>> Malcolm
>
> A small suggestion: since unget is expected to be called infrequently,
> next should better be faster for the common case instead of penalizing
> it with a try/except:
>
> def next(self):
> if not self.pushed_back:
> return self.it.next()
> else:
> return self.pushed_back.pop()
>
If speed is an issue then it may be better to avoid the test altogether:
def __init__(self, it):
self.it = it
self.pushed_back = []
self.nextfn = it.next
def __iter__(self):
return self
def __nonzero__(self):
if self.pushed_back:
return True
try:
self.pushback(self.nextfn())
except StopIteration:
return False
else:
return True
def popfn(self):
lst = self.pushed_back
res = lst.pop()
if not lst:
self.nextfn = self.it.next
return res
def next(self):
return self.nextfn()
def pushback(self, item):
self.pushed_back.append(item)
self.nextfn = self.popfn
More information about the Python-list
mailing list