true - while en python 3
Python: Continuando con la siguiente iteraciĆ³n en el bucle externo (7)
Acabo de hacer algo como esto. Mi solución para esto fue reemplazar el interior por bucle con una lista de comprensión.
for ii in range(200):
done = any([op(ii, jj) for jj in range(200, 400)])
...block0...
if done:
continue
...block1...
donde op es un operador booleano que actúa sobre una combinación de ii y jj. En mi caso, si alguna de las operaciones devolvió verdadero, estaba hecho.
Esto realmente no es tan diferente de romper el código en una función, pero pensé que usar el operador "any" para hacer un OR lógico en una lista de booleanos y hacer la lógica, todo en una línea, era interesante. También evita la llamada a la función.
Quería saber si hay alguna forma incorporada de continuar con la siguiente iteración en el bucle externo en Python. Por ejemplo, considere el código:
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
continue
...block1...
Quiero que esta instrucción continue salga del bucle jj y pase al siguiente elemento en el bucle ii. Puedo implementar esta lógica de alguna otra manera (estableciendo una variable de indicador), pero ¿hay alguna manera fácil de hacerlo, o es como pedir demasiado?
Creo que podrías hacer algo como esto:
for ii in range(200):
restart = False
for jj in range(200, 400):
...block0...
if something:
restart = True
break
if restart:
continue
...block1...
En otros idiomas, puede etiquetar el bucle y romper el bucle etiquetado. Python Enhancement Proposal (PEP) 3136 sugirió agregar esto a Python, pero Guido lo rechazó :
Sin embargo, lo estoy rechazando sobre la base de que el código tan complicado para requerir esta característica es muy raro. En la mayoría de los casos, existen soluciones alternativas que producen código limpio, por ejemplo, utilizando ''retorno''. Aunque estoy seguro de que hay algunos (raros) casos reales en los que la claridad del código sufriría una refactorización que hace posible el uso del retorno, esto se compensa con dos problemas:
La complejidad añadida al lenguaje, permanentemente. Esto afecta no solo a todas las implementaciones de Python, sino también a todas las herramientas de análisis de fuentes, además de toda la documentación del lenguaje.
Mi expectativa es que la función se usará más de lo que se usará correctamente, lo que generará una disminución neta en la claridad del código (medida en todo el código de Python escrito a partir de ahora). Los programadores perezosos están en todas partes, y antes de que te des cuenta tienes un desorden increíble en tus manos de código ininteligible.
Entonces, si eso es lo que esperabas, no tienes suerte, pero mira una de las otras respuestas, ya que hay buenas opciones allí.
Otra forma de lidiar con este tipo de problema es usar Exception ().
for ii in range(200):
try:
for jj in range(200, 400):
...block0...
if something:
raise Exception()
except Exception:
continue
...block1...
Por ejemplo:
for n in range(1,4):
for m in range(1,4):
print n,''-'',m
resultado:
1-1
1-2
1-3
2-1
2-2
2-3
3-1
3-2
3-3
Suponiendo que queremos saltar al bucle n externo de m loop si m = 3:
for n in range(1,4):
try:
for m in range(1,4):
if m == 3:
raise Exception()
print n,''-'',m
except Exception:
continue
resultado:
1-1
1-2
2-1
2-2
3-1
3-2
Enlace de referencia: http://www.programming-idioms.org/idiom/42/continue-outer-loop/1264/python
Queremos encontrar algo y luego detener la iteración interna. Yo uso un sistema de banderas.
for l in f:
flag = True
for e in r:
if flag==False:continue
if somecondition:
do_something()
flag=False
for i in ...:
for j in ...:
for k in ...:
if something:
# continue loop i
En un caso general, cuando tiene múltiples niveles de bucle y la break
no funciona para usted (porque desea continuar uno de los bucles superiores, no el derecho sobre el actual), puede hacer uno de los siguientes:
Refactorice los bucles de los que desea escapar a una función
def inner():
for j in ...:
for k in ...:
if something:
return
for i in ...:
inner()
La desventaja es que es posible que deba pasar a esa nueva función algunas variables, que anteriormente estaban dentro del alcance. Puede pasarlos como parámetros, convertirlos en variables de instancia en un objeto (crear un nuevo objeto solo para esta función, si tiene sentido), o variables globales, singletons, cualquiera (ehm, ehm).
O puede definir inner
como una función anidada y dejar que solo capture lo que necesita (¿puede ser más lento?)
for i in ...:
def inner():
for j in ...:
for k in ...:
if something:
return
inner()
Use excepciones
Filosóficamente, esto es para qué sirven las excepciones, rompiendo el flujo del programa a través de los bloques de construcción de programación estructurada (si, para, mientras) cuando sea necesario.
La ventaja es que no tiene que dividir el código en varias partes. Esto es bueno si se trata de algún tipo de cálculo que está diseñando mientras lo escribe en Python. La introducción de abstracciones en este punto inicial puede ralentizarte.
Lo malo de este enfoque es que los autores de intérpretes / compiladores suelen suponer que las excepciones son excepcionales y se optimizan en consecuencia.
class ContinueI(Exception):
pass
continue_i = ContinueI()
for i in ...:
try:
for j in ...:
for k in ...:
if something:
raise continue_i
except ContinueI:
continue
Cree una clase de excepción especial para esto, para que no se arriesgue a silenciar accidentalmente alguna otra excepción.
Algo completamente diferente
Estoy seguro de que aún hay otras soluciones.
for ii in range(200):
for jj in range(200, 400):
...block0...
if something:
break
else:
...block1...
Break
romperá el bucle interno, y block1 no se ejecutará (se ejecutará solo si el bucle interno se sale normalmente).