for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
desde el tercer bucle ¿cómo salgo del bucle actual y voy al siguiente valor de for row in b:
?python: salir de dos bucles
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
desde el tercer bucle ¿cómo salgo del bucle actual y voy al siguiente valor de for row in b:
?python: salir de dos bucles
Ésta utiliza un booleano para ver si ha terminado aún:
done = False
for x in xs:
for y in ys:
if bad:
done = True
break
if done:
break
Esto lo hará continue
si no se utilizó descanso. El else
se omitirá si hubo un corte, por lo que verá el siguiente break
. Este enfoque tiene el beneficio de no tener que usar una variable, pero puede ser más difícil de leer para algunos.
for x in xs:
for y in ys:
if bad:
break
else:
continue
break
Bueno, tenía tres bucles, no dos. –
Bueno, pensé que quizás OP podría extrapolar a tres bucles. –
@Teodor: leer q. con cuidado: el bucle más externo no necesita salir, por lo que el ejemplo w/2 loops es lo correcto –
No comprobado:
inner_termination=False
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
<blah>
if break_condition:
inner_termination=True
break
<blah>
if inner_termination:
inner_termination=False
break
for row in b:
more_drugs = True
for drug in drug_input:
for brand in brand_names[drug]:
if something:
more_drugs = False
break
if not more_drugs:
break
Python no tiene una estructura de control para romper a partir de dos bucles a la vez, por lo que hay que hacer algo manual de este modo.
@cjrh: Tengo curiosidad: ¿por qué escribiría "Gran respuesta "pero no vota la respuesta? Sin presión ... –
¿Has visto mi respuesta? –
¡Ah, ahora lo entiendo! :) –
Si tiene tres niveles de bucle en un método, probablemente necesite replantear su diseño.
all
y any
para evitar escribir bucles explícitos.Hacer cualquiera de estos debe significar que ya no tiene este problema.
No estoy seguro de estar de acuerdo con eso, específicamente en el caso de la iteración sobre una estructura de datos compleja. ¡A veces solo tienes diccionarios en diccionarios en diccionarios! – katrielalex
@karielalex: ¿No estás de acuerdo con los dos puntos, o solo con el segundo? –
Con "Si tienes tres niveles de bucle en un método, entonces probablemente necesites replantear tu diseño". Creo que hay una diferencia entre el caso de iterar sobre una estructura de datos, en cuyo caso la iteración múltiple es semánticamente una sección y no debería dividirse o eliminarse, y el caso donde se hace demasiado en un solo lugar . En la última situación, estoy de acuerdo con ambos puntos. Por ejemplo, recientemente construí un DFA que tenía una tabla de transición 'initial node' ->' arc type' -> 'guard' ->' node final'. Para iterar sobre todos los bordes, necesitas tres bucles. – katrielalex
for row in b:
ok = True
for drug in drug_input:
if not ok:
break;
for brand in brand_names[drug]:
if not ok:
break
if whatever:
ok = False
try
/except
/raise
, como se sugiere en el comentario de @ GDDC, es una posibilidad. Otra es "envolver" los dos bucles anidados en una sola:
for row in b:
for brand in (b for d in drug_input for b in brand_names[d]):
...
ahora, un break
for brand
del bucle anidado irá de nuevo al nivel del bucle externo for row
. Por supuesto, esto solo funciona cuando el código que aquí se reemplaza por ...
no necesita ver el nombre drug
vinculado al medicamento que se está examinando actualmente. ¿Es ese el caso para ti?
Lo suficientemente simple para obtener el nombre del medicamento es obligatorio. 'para marca, droga en ((b, d) para d en drug_input para b en brand_names [d]):' –
Consideraría poner dos bucles interiores en la función y usando devolver desde allí. Probablemente, reconsiderar lo que estás haciendo y cómo se da la mejor alternativa a eso.
¿Podría dar su pseudo código actual, entrada y salida, para que podamos tratar de eliminar la necesidad del descanso en primer lugar? Necesitamos ver dónde se utilizan las variables de bucle o, mejor aún, cuál es el objetivo del procesamiento.
latidos manejo de excepciones establecer variables de todo el lugar de la OMI
for row in b:
for drug in drug_input:
try:
for brand in brand_names[drug]:
if some_condition:
raise StopIteration
except StopIteration:
break
¡Las excepciones son solo para situaciones excepcionales! –
"Esto se deriva de Exception en lugar de StandardError, ya que esto no se considera un error en su aplicación normal." http://docs.python.org/library/exceptions.html#exceptions.StopIteration – brianz
Ok, eso fue un regreso bastante bueno :) Pero en serio, no maneje excepciones para el flujo de control. En cualquier idioma. Un controlador try-except es una señal visual muy, muy extendida para "algo inusual que acaba de suceder". –
reciente PEP veo que solicita esta característica es de 3136 (y fue rechazada): http://mail.python.org/pipermail/python-3000/2007-July/008663.html
más cercano & lo más limpio que podía ver a lo lo que quiere hacer sería hacer lo siguiente (y dado que incluso los nombres de tipo tienen un alcance, puede declarar LocalBreak dentro de la función que necesita):
class LocalBreak(Exception): pass
try:
for i in ...:
for h in ...:
for j in ...:
if should_break(j):
raise LocalBreak()
except LocalBreak:
pass
for a in aa:
for b in bb:
for c in cc:
if c == a[b]:
break
else:
continue
break
Python admite for...else
declaraciones. El bloque else
se evalúa si el break
interno no se activa.
lo siento, ¿puedes decirme qué añade esto al contenido actual? –
Si tiene demasiados bucles incrustados, podría ser el momento de un refactor. En este caso, creo que el mejor refactor es mover sus bucles en una función y usar una declaración return
. Eso forzará la salida de cualquier cantidad de bucles. Por ejemplo:
def example(self, drug_input):
ok = False
for x in drug_input["names"]:
for y in range(drug_input["number_of_drugs"]):
for z in drug_input["list_of_drugs"]:
# do stuff
if ok:
return drug_costs
Ahora, tal vez reformulando su lógica de este tipo es complicado, pero apuesto a la refactorización será ayudar de otras maneras.
Probablemente envolvería este bloque en un intento y me largaría con un aumento. –
por favor muéstrame cómo –
¿Puedo preguntar qué condición en el lazo interno forzaría un 'break'? –