¿Cómo puedo salir de múltiples bucles?

Resuelto Matthew Scharley asked hace 16 años • 40 respuestas

Dado el siguiente código (que no funciona):

while True:
    # Snip: print out current state
    while True:
        ok = get_input("Is this ok? (y/n)")
        if ok.lower() == "y": break 2 # This doesn't work :(
        if ok.lower() == "n": break

    # Do more processing with menus and stuff

¿Hay alguna manera de hacer que esto funcione? ¿O tengo que hacer una verificación para salir del bucle de entrada y luego otra verificación más limitada en el bucle exterior para salir todos juntos si el usuario está satisfecho?

Matthew Scharley avatar Oct 10 '08 07:10 Matthew Scharley
Aceptado

Mi primer instinto sería refactorizar el bucle anidado en una función y usarlo returnpara salir.

Robert Rossney avatar Oct 10 '2008 00:10 Robert Rossney

Aquí hay otro enfoque que es breve. La desventaja es que sólo puedes romper el bucle exterior, pero a veces es exactamente lo que quieres.

for a in xrange(10):
    for b in xrange(20):
        if something(a, b):
            # Break the inner loop...
            break
    else:
        # Continue if the inner loop wasn't broken.
        continue
    # Inner loop was broken, break the outer.
    break

Esto utiliza la construcción for/else explicada en: ¿ Por qué Python usa 'else' después de los bucles for y while?

Idea clave: Parece que el bucle exterior siempre se rompe. Pero si el bucle interior no se rompe, el bucle exterior tampoco lo hará.

La continuedeclaración es la magia aquí. Está en la cláusula "for-else". Por definición , eso sucede si no hay una ruptura interna. En esa situación continuese evita hábilmente la rotura exterior.

yak avatar Jun 30 '2010 14:06 yak

PEP 3136 propone la etiqueta pausa/continuar. Guido lo rechazó porque "un código tan complicado que requiera esta característica es muy raro". Sin embargo, el PEP menciona algunas soluciones (como la técnica de excepción), mientras que Guido cree que refactorizar para usar return será más sencillo en la mayoría de los casos.

John Fouhy avatar Oct 10 '2008 03:10 John Fouhy

Primero, la lógica ordinaria es útil.

Si, por alguna razón, las condiciones de terminación no se pueden resolver, las excepciones son un plan alternativo.

class GetOutOfLoop( Exception ):
    pass

try:
    done= False
    while not done:
        isok= False
        while not (done or isok):
            ok = get_input("Is this ok? (y/n)")
            if ok in ("y", "Y") or ok in ("n", "N") : 
                done= True # probably better
                raise GetOutOfLoop
        # other stuff
except GetOutOfLoop:
    pass

Para este ejemplo específico, es posible que no sea necesaria una excepción.

Por otro lado, muchas veces tenemos las opciones "Y", "N" y "Q" en las aplicaciones en modo caracteres. Para la opción "Q", queremos una salida inmediata. Eso es más excepcional.

S.Lott avatar Oct 10 '2008 00:10 S.Lott