Dynamically generating a flexible number of nested for loops [duplicate]

本秂侑毒 提交于 2019-12-23 06:12:56

问题


Is it possible to add/reduce number of nested for loops in a function based on the length of input?

For example: Based on a certain input of length 3, I may need to use 1 nested for loop (for loop inside another for loop). Similar to this,

for i in range(0, len(input)+1):
    for j in range(i+1, len(input)+1):

However, when the input length is 4, I could have achieved my result if I could introduce additional for loop inside the already existing nested for loop, which means,

for i in range(0, len(input)+1):
    for j in range(i+1, len(input)+1):
        for k in range(j+1, len(input)+1):`

Similarly, if the input length is 5, then I would like to introduce another for loop,

for i in range(0, len(input)+1):
    for j in range(i+1, len(input)+1):
        for k in range(j+1, len(input)+1):
            for l in range(k+1, len(input)+1):`

The pattern is, there will be n-1 number of for loops for an input of length n.

Is it possible create such a function in Python?


回答1:


From this article the code written in C and hastily translated to python gives you this:

If we look at how the nested loops work, we see that the inner most loop works most of time and the upper loops are needed only when we run out of values in the inner loops.

To convert this into a dynamic nested loop we can represent the different loop variables in an array. For simplicity lets assume that the upper bound of these variables are a constant as in the above example.

To implement a dynamic nested loop we need to increment the inner most loop variable until we run out values. Only then do we need to look at changing the upper level loop variables.

While this snippet is generating combinatorics, it is maybe possible to imagine re-using it for a different purpose.

As mentioned in the comments, it may not be a good design choice.
There has to be a better (more pythonic) way using generators, or maybe async, than increasing the level of indirection.

Of course, there is also recursion, but that was not the point of the question.

Generating dynamically nested loops

MAXROWS = 4      #    contains the number of levels
MAXVALUES = 2    #    contains the maximum combination for a given nested variables.

display = ['1', '2', '3', '4', '5', '6', '7', '8', '9']

arrs = [0] * MAXROWS   # represent the different variables in the for loops                      
status = False

while not status: 

    total = 0
    # calculate total for exit condition
    for r in range(MAXROWS):
        total += arrs[r]
        # test for exit condition
    if total == (MAXVALUES - 1) * MAXROWS:
        status = True

    # printing
    for r in range(MAXROWS):
        print(display[arrs[r]], end=' ')  # print(arrs[r])
    print()

    # increment loop variables
    change = True
    r = MAXROWS-1    # start from innermost loop

    while change and r >= 0:
    # increment the innermost variable and check if spill overs
        if (arrs[r] + 1) > MAXVALUES-1:    
            arrs[r] += 1
            arrs[r] = 0     #  // reintialize loop variable
            # Change the upper variable by one
            # We need to increment the immediate upper level loop by one
            change = True   
        else:
            arrs[r] += 1
            change = False   # Stop as there the upper levels of the loop are unaffected

            # We can perform any inner loop calculation here arrs[r]

        r -= 1  #  move to upper level of the loop

output:

1 1 1 1 
1 1 1 2 
1 1 2 1 
1 1 2 2 
1 2 1 1 
1 2 1 2 
1 2 2 1 
1 2 2 2 
2 1 1 1 
2 1 1 2 
2 1 2 1 
2 1 2 2 
2 2 1 1 
2 2 1 2 
2 2 2 1 
2 2 2 2


来源:https://stackoverflow.com/questions/52456836/dynamically-generating-a-flexible-number-of-nested-for-loops

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