ranges = [(0, 100, 'a'), (0, 75, 'b'), (95, 150, 'c'), (120, 130, 'd')]
endpoints = sorted(list(set([r[0] for r in ranges] + [r[1] for r in ranges])))
start = {}
end = {}
for e in endpoints:
    start[e] = set()
end[e] = set()
for r in ranges:
    start[r[0]].add(r[2])
end[r[1]].add(r[2])
current_ranges = set()
for e1, e2 in zip(endpoints[:-1], endpoints[1:]):
    current_ranges.difference_update(end[e1])
current_ranges.update(start[e1])
print('%d - %d: %s' % (e1, e2, ','.join(current_ranges)))
How to divide a set of overlapping ranges into non-overlapping ranges?