Antoon Pardon wrote: > I need an interator that takes an already existing iterator and > divides it into subiterators of items belonging together. > > For instance take the following class, wich would check whether > the argument is greater or equal to the previous argument. > > class upchecker: > def __init__(self): > self.prev = None > def __call__(self, arg): > if self.last is None: > self.prev = arg > return True > elif arg >= self.last: > self.prev = arg > return True > else: > self.prev = arg > return False > > So the iterator I need --- I call it grouped --- in combination with > the above class would be used someting like: > > for itr in grouped([8, 10, 13, 11, 2, 17, 5, 12, 7, 14, 4, 6, 15, 16, 19, > 9, 0, 1, 3, 18], upchecker()): > print list(itr) > > and the result would be: > > [8, 10, 13] > [11] > [2, 17] > [5, 12] > [7, 14] > [4, 6, 15, 16, 19] > [9] > [0, 1, 3, 18] > > Anyone an idea how I best tackle this?
I always start thinking "There must be an elegant way to do this" and then end with a clumsy wrapper around itertools.groupby(). $ cat grouped.py from itertools import groupby class Check: def __init__(self, check): self.first = True self.prev = None self.toggle = False self.check = check def __call__(self, item): if self.first: self.first = False else: if not self.check(self.prev, item): self.toggle = not self.toggle self.prev = item return self.toggle def grouped(items, check): return (g for k, g in groupby(items, Check(check))) if __name__ == "__main__": def upchecker(a, b): return a < b items = [ 8, 10, 13, 11, 2, 17, 5, 12, 7, 14, 4, 6, 15, 16, 19, 9, 0, 1, 3, 18 ] for itr in grouped(items, upchecker): print(list(itr)) $ python grouped.py [8, 10, 13] [11] [2, 17] [5, 12] [7, 14] [4, 6, 15, 16, 19] [9] [0, 1, 3, 18] -- https://mail.python.org/mailman/listinfo/python-list