an iterator that keeps a list of the next and previous items in a fixed length window. For instance, one can obtain the 10 items that are ahead the current one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import collections
class itercontext:
'''an iterator that allows accessing previous and next elements'''
def __init__(self,it,countprevious,countcomingnext):
'''initializes the iterator
it: the underlying iterator
countprevious: number of elements to keep after being visited
countcomingnext: number of elements to look ahead
'''
self.iter=iter(it)
# current element
self.current=None
self.existcurrent=False
# list of previous and next elements
self.comingnext=collections.deque()
self.previous=collections.deque()
self.countprevious=countprevious
try:
for i in range(countcomingnext):
self.comingnext.append(self.iter.next())
except StopIteration:
pass
def __iter__(self):
return self
def next(self):
try:
self.comingnext.append(self.iter.next())
except StopIteration:
pass # if the underlying iterator is exhausted, empty comingnext
if len(self.comingnext)==0:
raise StopIteration # if no more item ahead, stop
if self.existcurrent: self.previous.append(self.current)
self.current=self.comingnext.popleft()
self.existcurrent=True
if len(self.previous)>self.countprevious:
self.previous.popleft()
return self.current
def getComingnext(self):
return self.comingnext
def getPrevious(self):
return self.previous
def listcomingnext(self):
return list(self.comingnext)
def listprevious(self):
return list(self.previous)
|
When it is needed to know what are the next N elements or previous N elements in an iterator, this recipe avoids converting first the iterator to a list. For instance, - printing the 2 lines before and after a line when searching a match in a file. (like in grep -c) for line in itercontext(file(name),2,2): if x.match(line) print '\n'.join(i.listcomingnext()) print line print '\n'.join(i.listprevious())
- calculating a moving average over a window.