Would like some thoughts on a grouped iterator.
breamoreboy at gmail.com
breamoreboy at gmail.com
Mon Sep 5 05:59:11 EDT 2016
On Monday, September 5, 2016 at 10:42:27 AM UTC+1, Peter Otten wrote:
> 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]
As usual you beat me to it, but I'd spell "upchecker" as "from operator import lt" :)
More information about the Python-list
mailing list