Home > Back-end >  Mimicing 'n' Nested For Loops Using Recursion
Mimicing 'n' Nested For Loops Using Recursion

Time:01-20

I would like to create some number of for-loops equal to the length of a list, and iterate through the values in that list. For example, if I had the list:

[1,2,3,4]

I would like the code to function like:

for i in range(1):
    for j in range(2):
        for k in range(3):
            for l in range(4):
                myfunc(inputs)

I understand I would need to do this recursively, but I'm not quite sure how. Ideally, I would even be able to iterate through these list values by a variable step; perhaps I want to count by two's for one loop, by .8's for another, etc. In that case, I would probably deliver the information in a format like this:

[[value,step],[value,step] ... [value,step],[value,step]]

So, how could I do this?

CodePudding user response:

Not quite sure what you want at the very end, but here's a way to recursively set-up your loops:

test = [1,2,3,4]

def recursive_loop(test):
    if len(test) == 1:
        for i in range(test[0]):
            print('hi') # Do whatever you want here
        
    elif len(test) > 1:
        for i in range(test[0]):
            recursive_loop(test[1:])
            
recursive_loop(test)

CodePudding user response:

You can certainly do it with recursion, but there's already a library function for that:

itertools.product

from itertools import product

def nested_loops(myfunc, l):
    for t in product(*(range(n) for n in l)):
        myfunc(*t)

## OR EQUIVALENTLY
# def nested_loops(myfunc, l):
#     for t in product(*map(range, l)):
#         myfunc(l)

nested_loops(print, [1, 2, 3, 4])
# 0 0 0 0
# 0 0 0 1
# 0 0 0 2
# 0 0 0 3
# 0 0 1 0
# 0 0 1 1
# ...
# 0 1 2 1
# 0 1 2 2
# 0 1 2 3

You can of course include steps too. Library function zip can be useful.

def nested_loops_with_steps_v1(myfunc, upperbounds, steps):
    for t in product(*(range(0, n, s) for n,s in zip(upperbounds, steps))):
        myfunc(*t)

nested_loops_with_steps_v1(print, [1,2,8,10], [1,1,4,5])
# 0 0 0 0
# 0 0 0 5
# 0 0 4 0
# 0 0 4 5
# 0 1 0 0
# 0 1 0 5
# 0 1 4 0
# 0 1 4 5

Or if your steps and upperbounds are already zipped together:

def nested_loops_with_steps_v2(myfunc, l):
    for t in product(*(range(0, n, s) for n,s in l)):
        myfunc(*t)

nested_loops_with_steps_v2(print, [(1,1),(2,1),(8,4),(10,5)])
# 0 0 0 0
# 0 0 0 5
# 0 0 4 0
# 0 0 4 5
# 0 1 0 0
# 0 1 0 5
# 0 1 4 0
# 0 1 4 5
  • Related