Welcome, guest | Sign In | My Account | Store | Cart

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.

Python, 47 lines
 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.