Dynamic For Loops in Python

三世轮回 提交于 2021-02-16 15:32:29

问题


i understand that to create dynamic for loops, recursive or itertools module in python is the way to go. Lets say I am doing it in recursive.

What I want is

for var1 in range(var1_lowerlimit, var1_upperlimit, var1_stepsize):
    for var2 in range(var2_lowerlimit, var2_upperlimit, var2_stepsize):
    :
    :
        # do_whatever()

repeat for n loops where n is the number of variables

What I have now is I have 2 lists

variable_list = [ var1, var2, var3, ... ]
boundaries_list = [ [var1_lowerlimit, var1_upperlimit, var1_stepsize], 
                    [var2_lowerlimit, var2_upperlimit, var2_stepsize], ...]

def dynamic_for_loop(variable_list , boundaries_list, no_of_loops, list_index = 0):
    if no_of_loops <= 0:
        # do_whatever()
    else:
        lower_bound = boundaries_list[list_index][0]
        upper_bound = boundaries_list[list_index][1]
        step_size = boundaries_list[list_index][2]
        for index in range(lower_bound, upper_bound, step_size):
            list_index += 1
            try:
                dynamic_for_loop(variable_list , boundaries_list, no_of_loops - 1, list_index)
            except:
                list_index = 0
                dynamic_for_loop(variable_list , boundaries_list, no_of_loops - 1, list_index)

I did a reset on list_index as it gets out of range, but i couldn't get the result I want. Can someone enlighten me what went wrong?


回答1:


Use the itertools.product() function to generate the values over a variable number of ranges:

for values in product(*(range(*b) for b in boundaries_list)):
    # do things with the values tuple, do_whatever(*values) perhaps

Don't try to set a variable number of variables; just iterate over the values tuple or use indexing as needed.

Using * in a call tells Python to take all elements of an iterable and apply them as separate arguments. So each b in your boundaries_list is applied to range() as separate arguments, as if you called range(b[0], b[1], b[2]).

The same applies to the product() call; each range() object the generator expression produces is passed to product() as a separate argument. This way you can pass a dynamic number of range() objects to that call.




回答2:


Just for fun, I thought that I would implement this using recursion to perhaps demonstrate the pythonic style. Of course, the most pythonic way would be to use the itertools package as demonstrated by Martijn Pieters.

def dynamic_for_loop(boundaries, *vargs):
    if not boundaries:
        print(*vargs) # or whatever you want to do with the values
    else:
        bounds = boundaries[0]
        for i in range(*bounds):
            dynamic_for_loop(boundaries[1:], *(vargs + (i,)))

Now we can use it like so:

In [2]: boundaries = [[0,5,1], [0,3,1], [0,3,1]]

In [3]: dynamic_for_loop(boundaries)
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
1 0 1
1 0 2
1 1 0
1 1 1
1 1 2
1 2 0
1 2 1
1 2 2
2 0 0
2 0 1
2 0 2
2 1 0
2 1 1
2 1 2
2 2 0
2 2 1
2 2 2
3 0 0
3 0 1
3 0 2
3 1 0
3 1 1
3 1 2
3 2 0
3 2 1
3 2 2
4 0 0
4 0 1
4 0 2
4 1 0
4 1 1
4 1 2
4 2 0
4 2 1
4 2 2


来源:https://stackoverflow.com/questions/38068669/dynamic-for-loops-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!