Geremia
Geremia

Reputation: 5636

Group by first element, find ranges of second element

For a list like this (sorted by the first and then second elements):

[[1,3],[1,4],[1,5],[1,7],[1,8],[1,10],[3,5],[3,6],[3,8],…]

I would like a function that groups by the first element and gives ranges for the second element:

[[1,[(3,5),(7,8),10],[3,[(5,6),8]],…]

Upvotes: -4

Views: 86

Answers (1)

Stef
Stef

Reputation: 15525

Using functions map_reduce and consecutive_groups from module more_itertools:

from more_itertools import map_reduce, consecutive_groups
from operator import itemgetter

# MUST BE SORTED
l = [[1,3],[1,4],[1,5],[1,7],[1,8],[1,10],[3,5],[3,6],[3,8]]

def first_and_last(group):
    first = next(group)
    last = first
    for last in group:
        pass
    return (first, last) if last != first else first

def get_intervals(sorted_values):
    return list(map(first_and_last, consecutive_groups(sorted_values)))

r = map_reduce(l,
               keyfunc=itemgetter(0),
               valuefunc=itemgetter(1),
               reducefunc=get_intervals)

print(r)
# defaultdict(None, {1: [(3, 5), (7, 8), 10], 3: [(5, 6), 8]})

Upvotes: 1

Related Questions