3

How can you loop across multiple different ranges. for example say i want to run a for loop for specific set of ranges

1 to 2, 4 to 6 and 10 to 13,

I don't know the exact final number so maybe a function might be useful.

The standard method of

for i in range(1,2) + range (4,6) + range (10,13)

I should have this

[1,4,5,6,10,11,13]

My question is, this is not so efficient, if i don't know the total number of ranges am covering, and I can't even create this as a function without so many parameters.

so if i want to have something like this

for i in range(a,b) + range (c,d) + range (e,f), ..... 

but as a simple function Can someone help with an efficient way of doing this ?

1
  • 1
    The call range(1,2) returns 1 not 1 and 2 Commented May 15, 2021 at 14:35

3 Answers 3

4

Simple, though most likely the least efficient solution is to use a nested for loop,

def multi_range_loop(ranges):

    all_values = []
    for rg in ranges:
        for i in range(rg[0], rg[1]):
            all_values.append(i)
    print(all_values)

my_ranges = [[1,3],[4,7],[10,14]]
multi_range_loop(my_ranges)
Sign up to request clarification or add additional context in comments.

Comments

2

You can chain the ranges with itertools:

from itertools import chain

total_range = chain(range(1,2), range(4,6), range(10,13))

print(list(total_range))
#[1, 4, 5, 10, 11, 12]

Here is another solution with a function that returns a generator:

def total_range(lst):
    return (i for tup in lst for i in range(tup[0], tup[1]))

list_of_ranges = [(1,2), (4,6), (10,13)]
print(list(total_range(list_of_ranges)))

3 Comments

this doesn't solve the problem. I need it as a function
What are the arguments for your desired function? A list of ranges? If so, you can easily incorporate this code in a function.
@mufty__py See my amended answer. I created a function that takes in a list of tuples that correspond to a discontinuous range and returns a generator that can be used like a range.
1

To have an iterable object from the list of iterable form the different ranges you can use the chain function as in the following response https://stackoverflow.com/a/67547449/1287983.

And in order to have dynamic ranges in a function you can do the following:

def get_ranges(list_ranges):
    lower_bounds, upper_bounds = zip(*list_ranges)
    return list(chain(*list(map(
        range, lower_bounds, upper_bounds))))

get_ranges([(1,2), (4,6), (10,13)])

[1, 4, 5, 10, 11, 12]

The function above returns the list of values. And if you want to iterate efficiently over the resulting values, you just need to return the iterator instead of the list. See the code below.

def get_ranges(list_ranges):
    lower_bounds, upper_bounds = zip(*list_ranges)
    return chain(*list(map(range, lower_bounds, upper_bounds)))

for val in get_ranges([(1,2), (4,6), (10,13), (2,5)]):
    print(val)

1 4 5 10 11 12 2 3 4

2 Comments

How can this be used in a for loop?
@mufty__py I edited the response by adding the way to use the result in a for loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.