Necesito emular un ciclo do-while en un programa Python. Desafortunadamente, el siguiente código directo no funciona:
list_of_ints = [ 1, 2, 3 ]
iterator = list_of_ints.__iter__()
element = None
while True:
if element:
print element
try:
element = iterator.next()
except StopIteration:
break
print "done"
En lugar de "1,2,3, hecho", imprime el siguiente resultado:
[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', ' File "test_python.py", line 8, in <module>
s = i.next()
', 'StopIteration
']
¿Qué puedo hacer para detectar la excepción 'detener iteración' y romper un bucle while correctamente?
Un ejemplo de por qué tal cosa puede ser necesaria se muestra a continuación como pseudocódigo.
Máquina estatal:
s = ""
while True :
if state is STATE_CODE :
if "//" in s :
tokens.add( TOKEN_COMMENT, s.split( "//" )[1] )
state = STATE_COMMENT
else :
tokens.add( TOKEN_CODE, s )
if state is STATE_COMMENT :
if "//" in s :
tokens.append( TOKEN_COMMENT, s.split( "//" )[1] )
else
state = STATE_CODE
# Re-evaluate same line
continue
try :
s = i.next()
except StopIteration :
break
python
while-loop
do-while
grigoryvp
fuente
fuente
s=i.next()
lugar de Ninguno y posiblemente haría un trabajo inicial en lugar de simplemente hacer que su primer paso por el bucle sea inútil.Respuestas:
No estoy seguro de lo que estás tratando de hacer. Puede implementar un ciclo do-while como este:
O:
¿Qué estás haciendo tratando de usar un bucle do while para imprimir las cosas en la lista? ¿Por qué no solo usar:
Actualizar:
Entonces, ¿tienes una lista de líneas? ¿Y quieres seguir iterando? Qué tal si:
¿Te parece algo parecido a lo que quieres? Con su ejemplo de código, sería:
fuente
Aquí hay una manera muy simple de emular un ciclo do-while:
Las características clave de un ciclo do-while son que el cuerpo del ciclo siempre se ejecuta al menos una vez, y que la condición se evalúa en la parte inferior del cuerpo del ciclo. La estructura de control que se muestra aquí cumple ambas cosas sin necesidad de excepciones o declaraciones de interrupción. Introduce una variable booleana adicional.
fuente
break
. Específicamente, si se necesita lógica DESPUÉStest_loop_condition()
, que no debe ejecutarse una vez que hayamos terminado, debe envolverseif condition:
. Por cierto,condition
es vago. Más descriptivo:more
onotDone
.break
en bucles y cuando lo encuentro en el código que mantengo, encuentro que el bucle, con mayor frecuencia, podría haberse escrito sin él. La solución presentada es, en mi opinión, la forma más clara de representar un do while build en python.has_no_errors
oend_reached
(en cuyo caso el ciclo comenzaríawhile not end_reached
Mi código a continuación podría ser una implementación útil, destacando la principal diferencia entre do-while vs mientras como yo lo entiendo
Entonces, en este caso, siempre pasa por el ciclo al menos una vez.
fuente
while condition or first_pass:
. Luego,condition
siempre se evalúa primero y en generalfirst_pass
se evalúa solo dos veces (primera y última iteración). No olvides inicializarcondition
antes del ciclo a lo que quieras.La excepción romperá el ciclo, por lo que también podría manejarlo fuera del ciclo.
Supongo que el problema con su código es que el comportamiento del
break
interiorexcept
no está definido. Por lo general,break
solo sube un nivel, por ejemplo, elbreak
interiortry
va directamente afinally
(si existe) un fuera deltry
ciclo, pero no fuera del ciclo.PEP relacionada: http://www.python.org/dev/peps/pep-3136
Pregunta relacionada: ruptura de bucles anidados
fuente
->
Puedes hacer una función:
Pero 1) es feo. 2) La condición debe ser una función con un parámetro, que se supone que debe rellenarse con cosas (es la única razón para no usar el clásico bucle while).
fuente
while True: stuff(); if not condition(): break
es una muy buena idea. ¡Gracias!Aquí hay una solución más loca de un patrón diferente: el uso de corutinas. El código sigue siendo muy similar, pero con una diferencia importante; no hay condiciones de salida en absoluto! La corutina (cadena de corutinas realmente) simplemente se detiene cuando deja de alimentarla con datos.
El código anterior recopila todos los tokens como tuplas
tokens
y supongo que no hay diferencia entre.append()
y.add()
en el código original.fuente
La forma en que hice esto es la siguiente ...
Esto me parece la solución simplista, me sorprende no haberlo visto aquí. Obviamente, esto también se puede invertir a
etc.
fuente
para un bucle do - while que contiene sentencias try
alternativamente, cuando no hay necesidad de la cláusula 'finalmente'
fuente
fuente
stuff
ser una función o que el cuerpo del código se repita.while condition:
porqueis True
está implícito.condition
depende de alguna variable interna destuff()
, porque esa variable no está definida en ese momento.Hack rápido:
Use así:
fuente
¿Por qué no lo haces?
?
fuente
Vea si esto ayuda:
Establezca un indicador dentro del controlador de excepciones y verifíquelo antes de trabajar en el s.
fuente
while not flagBreak:
y la eliminación deif (flagBreak) : break
.flag
Evito las variables nombradas: no puedo inferir lo que significa un valor verdadero o un valor falso. En su lugar, usedone
oendOfIteration
. El código se convierte enwhile not done: ...
.Si se encuentra en un escenario en el que realiza un bucle mientras un recurso no está disponible o algo similar que arroja una excepción, podría usar algo como
fuente
Para mí, un bucle while típico será algo como esto:
Podría incluir un bucle for..loop dentro del bucle while también, si la situación lo amerita, para recorrer otro conjunto de condiciones.
fuente