2010-04-08 82 views
30

Utilizo el siguiente método para romper el bucle doble en Python.Rompe el bucle anidado (doble) en Python

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

¿Hay una manera mejor de romper el lazo doble?

Respuesta

36

probablemente no es lo que usted está esperando, pero por lo general se desea tener un break después de establecer find a 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 

Otra forma es utilizar una expresión generador para aplastar la for en un solo bucle

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

También puede considerar el uso de itertools.product

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

+1 ¡simple pero elegante! –

+0

itertools.product() es un gran enfoque. –

+0

He aprendido algo hoy :) – wonzbak

5

Refactorice las funciones para que pueda regresar cuando encuentre su "bingo".

La propuesta para permitir ruptura explícita de bucles anidados ha sido rechazada: http://www.python.org/dev/peps/pep-3136/

+1

Este debería ser el más votadas respuesta de la OMI. –

9

La mayoría de veces que se puede utilizar una serie de métodos para hacer un solo bucle que hace lo mismo como un bucle doble.

En su ejemplo, se puede utilizar itertools.product para reemplazar el fragmento de código con

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

Las otras funciones itertools son buenos para otros patrones también.

+0

Creo que te refieres a 'itertools.product'. 'combination' produce n-length tuplas de una sola secuencia – Jimmy

+0

Creo que te refieres a' itertools.product' –

+0

oh bah .... Soy un idiota esta noche. – magcius

29

La forma recomendada de Python para romper bucles anidados es ... Excepción

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 
+2

¿De verdad? Nunca he visto excepciones recomendadas para nada excepto, bueno, cosas excepcionales. – dave

+10

Realmente, Python tiene un enfoque un poco diferente a las excepciones, y este uso está bien. – Guard

+0

Me gusta esta idea porque también cubre situaciones en las que necesita iterar sobre una lista bidimensional con bucles anidados. Algunas otras ideas no funcionan para eso porque el bucle for anidado usa la variable proporcionada por el bucle padre para obtener más de un elemento para iterar. – Shule

Cuestiones relacionadas