Hướng dẫn break outer loop python

Not as elegant as it should be

Hướng dẫn break outer loop python

Photo by Johannes Plenio on Unsplash

We all know that Python is an elegant programming language. But everything has weaknesses. Sometimes Python is not as elegant as it should be.

For example, when we need to break out of nested loops as follows:

for a in list_a:
for b in list_b:
if condition(a,b)…

Is there an easier way to break out of nested loops than throwing an exception? (In Perl, you can give labels to each loop and at least continue an outer loop.)

for x in range(10):
    for y in range(10):
        print x*y
        if x*y > 50:
            "break both loops"

I.e., is there a nicer way than:

class BreakIt(Exception): pass

try:
    for x in range(10):
        for y in range(10):
            print x*y
            if x*y > 50:
                raise BreakIt
except BreakIt:
    pass

Hướng dẫn break outer loop python

asked Mar 17, 2009 at 9:24

Michael KuhnMichael Kuhn

7,8356 gold badges25 silver badges26 bronze badges

3

for x in xrange(10):
    for y in xrange(10):
        print x*y
        if x*y > 50:
            break
    else:
        continue  # only executed if the inner loop did NOT break
    break  # only executed if the inner loop DID break

The same works for deeper loops:

for x in xrange(10):
    for y in xrange(10):
        for z in xrange(10):
            print x,y,z
            if x*y*z == 30:
                break
        else:
            continue
        break
    else:
        continue
    break

Hướng dẫn break outer loop python

Bob Stein

15k8 gold badges79 silver badges98 bronze badges

answered Mar 17, 2009 at 12:27

Markus JarderotMarkus Jarderot

84.6k20 gold badges135 silver badges137 bronze badges

17

It has at least been suggested, but also rejected. I don't think there is another way, short of repeating the test or re-organizing the code. It is sometimes a bit annoying.

In the rejection message, Mr van Rossum mentions using return, which is really sensible and something I need to remember personally. :)

answered Mar 17, 2009 at 9:27

3

If you're able to extract the loop code into a function, a return statement can be used to exit the outermost loop at any time.

def foo():
    for x in range(10):
        for y in range(10):
            print(x*y)
            if x*y > 50:
                return
foo()

If it's hard to extract that function you could use an inner function, as @bjd2385 suggests, e.g.

def your_outer_func():
    ...
    def inner_func():
        for x in range(10):
            for y in range(10):
                print(x*y)
                if x*y > 50:
                    return
    inner_func()
    ...

answered Mar 17, 2009 at 12:37

Mr FoozMr Fooz

106k5 gold badges69 silver badges100 bronze badges

2

Use itertools.product!

from itertools import product
for x, y in product(range(10), range(10)):
    #do whatever you want
    break

Here's a link to itertools.product in the python documentation: http://docs.python.org/library/itertools.html#itertools.product

You can also loop over an array comprehension with 2 fors in it, and break whenever you want to.

>>> [(x, y) for y in ['y1', 'y2'] for x in ['x1', 'x2']]
[
    ('x1', 'y1'), ('x2', 'y1'),
    ('x1', 'y2'), ('x2', 'y2')
]

John R Perry

3,6932 gold badges35 silver badges59 bronze badges

answered Oct 26, 2011 at 17:47

Fábio SantosFábio Santos

3,7011 gold badge24 silver badges31 bronze badges

5

Sometimes I use a boolean variable. Naive, if you want, but I find it quite flexible and comfortable to read. Testing a variable may avoid testing again complex conditions and may also collect results from several tests in inner loops.

    x_loop_must_break = False
    for x in range(10):
        for y in range(10):
            print x*y
            if x*y > 50:
                x_loop_must_break = True
                break
        if x_loop_must_break: break

answered May 16, 2011 at 20:50

HalberdierHalberdier

1,13411 silver badges15 bronze badges

1

If you're going to raise an exception, you might raise a StopIteration exception. That will at least make the intent obvious.

answered Aug 14, 2012 at 0:31

Hướng dẫn break outer loop python

dbndbn

12.2k3 gold badges56 silver badges84 bronze badges

2

You can also refactor your code to use a generator. But this may not be a solution for all types of nested loops.

answered Mar 17, 2009 at 10:29

J SJ S

1,0477 silver badges6 bronze badges

In this particular case, you can merge the loops with a modern python (3.0 and probably 2.6, too) by using itertools.product.

I for myself took this as a rule of thumb, if you nest too many loops (as in, more than 2), you are usually able to extract one of the loops into a different method or merge the loops into one, as in this case.

answered Mar 17, 2009 at 9:58

TethaTetha

4,7801 gold badge16 silver badges17 bronze badges