51

I use the following method to break the double loop in Python.

for word1 in buf1:
    find = False
    for word2 in buf2:
        ...
        if res == res1:
            print "BINGO " + word1 + ":" + word2
            find = True
    if find:
        break

Is there a better way to break the double loop?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
prosseek
  • 182,215
  • 215
  • 566
  • 871

4 Answers4

71

The recommended way in Python for breaking nested loops is... Exception

class Found(Exception): pass
try:
    for i in range(100):
        for j in range(1000):
            for k in range(10000):
               if i + j + k == 777:
                  raise Found
except Found:
    print i, j, k 
Guard
  • 6,816
  • 4
  • 38
  • 58
  • 12
    Really? I've never seen exceptions recommended for anything except, well, exceptional things. – dave Dec 29 '10 at 13:47
  • 13
    Really, Python has a bit different approach to exceptions, and this use is OK. – Guard Dec 29 '10 at 13:55
  • I like this idea because it also covers situations where you need to iterate over a two-dimensional list with nested for loops. Some other ideas don't work for that because the nested for loop uses the variable provided by the parent for loop to get more than one item to iterate over. – Brōtsyorfuzthrāx May 23 '14 at 22:06
  • Plus it doesn't require you to structure your code just so. – Brōtsyorfuzthrāx May 23 '14 at 22:11
  • 1
    I feel this one is better than the accepted answer. – lkahtz Aug 06 '20 at 10:59
  • I like the answer in general but it does not allow to "continue" instead of "break". Thus it is not so nicely generalizing – Daniel Böckenhoff Feb 01 '23 at 14:32
62

Probably not what you are hoping for, but usually you would want to have a break after setting find to True

for word1 in buf1: 
    find = False 
    for word2 in buf2: 
        ... 
        if res == res1: 
            print "BINGO " + word1 + ":" + word2 
            find = True 
            break             # <-- break here too
    if find: 
        break 

Another way is to use a generator expression to squash the for into a single loop

for word1, word2 in ((w1, w2) for w1 in buf1 for w2 in buf2):
    ... 
    if res == res1: 
        print "BINGO " + word1 + ":" + word2
        break 

You may also consider using itertools.product

from itertools import product
for word1, word2 in product(buf1, buf2):
    ... 
    if res == res1: 
        print "BINGO " + word1 + ":" + word2
        break 
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
16

Refactor using functions so you can return when you find your "bingo".

The proposal to allow explicit breaking out of nested loops has been rejected: http://www.python.org/dev/peps/pep-3136/

dkamins
  • 21,450
  • 7
  • 55
  • 59
14

Most times you can use a number of methods to make a single loop that does the same thing as a double loop.

In your example, you can use itertools.product to replace your code snippet with

import itertools
for word1, word2 in itertools.product(buf1, buf2):
    if word1 == word2:
        print "BINGO " + word1 + ":" + word2
        break

The other itertools functions are good for other patterns too.

Ben Millwood
  • 6,754
  • 24
  • 45
magcius
  • 636
  • 3
  • 7