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