Home > OS >  Getting complimentary index ranges given list of start and stop indices in Python
Getting complimentary index ranges given list of start and stop indices in Python

Time:01-27

Imagine you have an absolute range that goes from 1 through 120. Let's also say you have a list of start, stops to indicate ranges. For example, the list [1,10] means it includes the following:

1,2,3,4,5,6,7,8,9,10 . Let's say another start,stop list in the list is [20,45].

How do I generate a Python program to give me the complimentary start, stop values?

Expected output for example:

[[11, 19], [46, 120]]

I tried iterating through the values and doing something about getting the next list's start value and comparing to the existing end value to create a slice; however, I am not getting the expected solution.

Any assistance would be much appreciated.

CodePudding user response:

Ok, I think I may have solved it.

Would this work?

def comp_start_stop(start, length, inds):
    start_stop = []

    first_start = inds[0][0]
    last_end = inds[-1][1]

    if first_start > start:
        start_stop.append([start, first_start])
    
    if last_end < length:
        start_stop.append([last_end 1, length])

    for i in range(len(inds) - 1):
        cur_start, cur_end = inds[i]
        next_start, next_end = inds[i 1]
        
        reg = [cur_end 1, next_start]
    
        start_stop.append(reg)

    return start_stop

overall_length = 120

sample_start_stop = [[1, 10], [20, 45], [70,95]]

CodePudding user response:

One option is to decrement each range start, and increment every range end. You will then have the indices for each gap range. After that, all you need to do is consider the possible gaps between the start of your entire span, to the first range start, and the same for the final range end to your limit.

start = 1
length = 100
subsets = [3, 10], [20, 45], [70, 98]

ranges = [start-1], *subsets, [length 1]
between = []
for a, b in zip(ranges, ranges[1:]):
    s, e = a[-1] 1, b[0]-1
    between.append([s, e]) if s < e else None  # Change to <= to include 1 length spans

CodePudding user response:

A possible solution would use intspan.

from intspan import intspan

comp = intspan.from_ranges([[1,10],[20,45]]).complement(low=1, high=120).ranges()
print(comp)

Prints:

[(11, 19), (46, 120)]
  • Related