Several nested 'for' loops, continue to next iteration of outer loop if condition inside inner loop is true [duplicate]
Asked Answered
C

5

6

I know it is terribly inefficient and ugly code, but if I have three for loops, nested inside each other such as so:

for x in range(0, 10):
    for y in range(x+1, 11):
       for z in range(y+1, 11):
           if ...

I want to break the two inner loops and continue to the next iteration of the outer loop if the if statement is true. Can this be done?

Constantino answered 11/1, 2016 at 15:40 Comment(5)
AFAIK the Python founder refused to add a construct to do that because the code would become uglyTwotime
you could write it using variables to store state and test everytime you break / finish the loopBrouwer
@wil93 Are you referring to the constructs break and continue? They are recognised in Python, well in Python 3.4 anyway.Constantino
@Brouwer Yes, that does seem like the neatest solution possible, as tglaria has demostrated in his answer below.Constantino
I was referring to the labeled break/continue construct, but as I said it was rejected.Twotime
M
4

Check some variable after each loops ends:

for x in range(0, 10):
    for y in range(x+1, 11):
        for z in range(y+1, 11):
            if condition:
                variable = True
                break
            #...
        if variable:
            break;
        #...
Marismarisa answered 11/1, 2016 at 15:43 Comment(0)
K
2

Another option is to use exceptions instead of state variables:

class BreakException(Exception):
    pass

for x in range(0, 10):
    try:
        for y in range(x+1, 11):
           for z in range(y+1, 11):
               if True:
                   raise BreakException
    except BreakException:
        pass

I imagine this could be especially useful if bailing out of more than two inner loops.

Knelt answered 11/1, 2016 at 15:53 Comment(3)
Very helpful. This should be marked as the answer!Lanner
This is an anti-pattern, exceptions should not be used for the logic side of the codeLaryngitis
@Laryngitis tell that to the Python Devs who thought StopIteration was a good idea. Anyway, you are right. There are cleaner solutions, and I'm just realizing one of them has not been posted yet...Knelt
B
0
n = False
for x in range(0,10):
    if n == True:
        print(x,y,z)
    for y in range(x+1, 11):
        if n == True:
            break
        for z in range(y+1, 11):
            if z == 5:
                n = True
                break

(1, 2, 5)
(2, 2, 5)
(3, 3, 5)
(4, 4, 5)
(5, 5, 5)
(6, 6, 5)
(7, 7, 5)
(8, 8, 5)
(9, 9, 5)
Brouwer answered 11/1, 2016 at 15:49 Comment(0)
T
0

A possible solution is to merge the two inner loops to a single one (that can be terminated with break):

import itertools

for x in range(10):
    for y, z in itertools.combinations(range(x+1, 11), 2):
        if condition:
            break
Twotime answered 11/1, 2016 at 15:56 Comment(0)
K
0

Define a function for the inner loops and simply return when the condition is True.

def process_inner(x):
    for y in range(x+1, 11):
       for z in range(y+1, 11):
           if condition:
               return
           # ...


for x in range(0, 10):
    process_inner(x)

I now believe this is a cleaner solution than abusing exceptions or introducing control flow variables.

It's not obvious in the abstract example, but the fact that some loops should be aborted and others not is a sign that these loops have very different purposes. When this is the case, factoring them into separate functions will communicate that difference much clearer than a bunch of nested loops.

Knelt answered 25/3, 2022 at 22:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.