Would like some thoughts on a grouped iterator.

Peter Otten __peter__ at web.de
Mon Sep 5 05:41:59 EDT 2016


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]





More information about the Python-list mailing list