Ivan Novikov
Ivan Novikov

Reputation: 578

How to check if range is partially within another range python?

Not the best wording, but I'll try to explain.

I have 4 regions, 0 <= x < 10, 10 <= x < 30, 30 <= x < 50, 50 <= x < 90.

I'm writing a function which takes in x_min and x_max, and outputs the regions covered. One of the edge cases that I can't solve in a "good" way is what if the range spans across multiple regions, e.g. x_min = 15, x_max = 60, where the output would be:

output = {'region1' : False,
          'region2' : True,
          'region3' : True,
          'region4' : True}

My approach is below, the best solution I can come up with right now is to split the interval between x_min and x_max into 10, and check every number, but that adds 10 more loops (so for the x_min = 15, x_max = 60 example, it would involve checking 15, 19.5, 24 and so on until 60).

Is there a better and more scalable way to do this? I'm not sure which tools are available other than countless if - elif statements in a for loop.

def assign_regions(x_min, x_max):
    values = [x_min, x_max]
    output = {'region1' : False, # a dictionary to store the output
              'region2' : False,
              'region3' : False,
              'region4' : False}

    for x in values:
        if 0 <= x < 10:
            output['region1'] = True
        elif 10 <= x < 30:
            output['region2'] = True
        elif ........

Upvotes: 0

Views: 929

Answers (3)

ame
ame

Reputation: 456

I'd do something like:

Store your ranges in a dict:

ranges = {'region1' : {'min':0, 'max': 10},
          'region2' : {'min':10, 'max': 30},
          'region3' : {'min':30, 'max': 50},
          'region4' : {'min':50, 'max': 90}}

Iterate through dict and make comparisons:

def assign_regions(x_min, x_max):
    return {region: x_max>range_['min'] and x_min<range_['max']
            for region, range_
            in ranges.items()}

Upvotes: 0

Alain T.
Alain T.

Reputation: 42133

To test if two ranges overlap you only have to check that each range's start is less than the other range's end.

regions = { 'region1' : (0,10),
            'region2' : (10,30),
            'region3' : (30,50),
            'region4' : (50,90)}

x_min,x_max = 15,60

overlaps = { reg:x_min < r_max and r_min < x_max
             for reg,(r_min,r_max) in regions.items() }

print(overlaps)
# {'region1': False, 'region2': True, 'region3': True, 'region4': True}

Upvotes: 1

ForceBru
ForceBru

Reputation: 44878

You can store the ranges of each region and then check them in a loop:

values = [x_min, x_max]
region_info = {
    'region1': range(0, 10),
    'region2': range(10, 30),
    # and so on
}
output = {region: False for region in region_info}

for x in values:
    for region_name, its_range in region_info.items():
        if x in its_range:
            output[region_name] = True

Basically, you can replace if statements with some data (region_info) and a loop over it.

Upvotes: 0

Related Questions