4

How do I make a number of nested loops where depth is a parameter. I am thinking of a function which takes depth as a parameter

def make_nested_loops(depth):
    ...

And, the result for depth=3 is the following

for i1 in range(10):
    for i2 in range(i1 + 1, 10):
        for i3 in range(i2 + 1, 10):
            # do stuff

So far I've been able to do this using strings building and exec command. But I think there is better and more efficient way to do it.

4
  • Nested loops create a larger complexity. What is it you're looping through and what are you trying to accomplish? Commented Jul 7, 2017 at 13:37
  • Why? The inner loops depend on the containing loops, so you can't really flatten it. Commented Jul 7, 2017 at 13:38
  • 1
    By the way, what is make_nested_loops supposed to return? A loop isn't an object, it's a syntactic construct. Perhaps it should take a second argument that is a function to call that receives a tuple (i1, i2, ...) as an argument and is called where #do stuff occurs. Commented Jul 7, 2017 at 13:46
  • @chepner It is supposed to return a list or a dictionary of tuples, where each tuple's length is exactly the depth. Commented Jul 7, 2017 at 13:53

2 Answers 2

2

An inefficient but simple approach would be to use itertools.product and filter unwanted tuples:

def make_tuples(depth, n):
    for i in itertools.product(range(n), repeat=depth):
        if sorted(i) < i:
            continue
        yield i

More efficient would be a recursive generator:

def make_tuples(depth, n, start=0):
    if depth == 0:
        yield ()
    else:
        for x in range(start, n):
            for t in make_tuples(depth - 1, n, x + 1):
                yield (x,) + t

Using it would look like

for (i1, i2, i3) in make_tuples(3, 10):
    # do stuff with i1, i2, i3

If the depth is really dynamic, you can't of course unpack the tuples coming from make_tuples. The body will have to know what to do with tuples of fixed but unknown length.

for tpl in make_tuples(n, 10):
    # Do stuff with tpl
Sign up to request clarification or add additional context in comments.

1 Comment

Nice. Thanks @chepner
2

The max number of nested loops you can have is 21 I think. So what you could do is have 21 nested loops in your function, and check if desired depth has been achieved at each loop. If not, add one to current depth variable.

7 Comments

"The max number of nested loops you can have is 21" Source please?
@Rightleg I think she may be right. I checked here and one of the author's said 20 is the max. I'm still not 100% sure though and I'm still looking.
@ChristianDean Well I just tested and that's right, 19 works but 20 does not. For the record, it fails with SyntaxError: too many statically nested blocks. But I do want a source.
Actually I cannot upvote this answer as it is not a good answer to the question, but I want to thank for letting me know that Python had such a limitation.
My source is experience, I once tried to make a ton of nested loops and it crashed with more than 19.
|

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.