Search code examples
pythonsplitintervals

Split intervals longer than a threshold


I have a list of tuples, each defining an interval (start, end). I would like to split the intervals which are longer than a certain threshold.

Example:

Initial list: segs = [(0,100),(120,140),(160,200)] 
Threshold: 30

Desired output:

split_segs = [(0,30),(30,60),(60,90),(90,100),(120,140),(160,190),(190,200)]

I come up with this code.

thr = 30.
split_segs = []
for a,b in segs:
    if b-a < thr:
        split_segs.extend([(a,b)])
    else:
        n = int((b-a)/thr)
        for i in range(n):
            if b-(a + (i+1)*thr) < thr:
                split_segs.extend([(a+(i+1)*thr, b)])
            else:
                split_segs.extend([(a+i*thr, a+(i+1)*thr)])

It works but looks very clumsy to me. Any better or more pythonic solution?


Solution

  • You can do this slightly more elegantly by extending with a range that has a step of threshold:

    segs = [(0,100),(120,140),(160,200)]
    threshold = 30
    split_segs = []
    
    for seg in segs:
        (a, b) = seg
        diff = b - a
        if diff <= threshold:
            split_segs.append(seg)
        else:
            split_segs.extend((n - threshold, n) for n in range(a + threshold, b + 1, threshold))
            if diff % threshold:
                # complete the gap
                split_segs.append((b - diff % threshold, b))
    
    print(split_segs)