¿Cómo emular un bucle do- while?
Necesito emular un bucle do- while en un programa Python. Lamentablemente, el siguiente código sencillo 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 de "detener iteración" y romper un bucle while correctamente?
A continuación se muestra un ejemplo de por qué puede ser necesario algo así 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
No estoy seguro de lo que estás intentando hacer. Puedes implementar un bucle do- while como este:
while True:
stuff()
if fail_condition:
break
O:
stuff()
while not fail_condition:
stuff()
¿Qué estás haciendo al intentar usar un bucle do while para imprimir las cosas en la lista? ¿Por qué no utilizar simplemente:
for i in l:
print i
print "done"
Actualizar:
¿Tienes una lista de líneas? ¿Y quieres seguir repitiéndolo? Qué tal si:
for s in l:
while True:
stuff()
# use a "break" instead of s = i.next()
¿Te parece algo parecido a lo que te gustaría? Con tu ejemplo de código, sería:
for s in some_list:
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] )
break # get next s
else:
state = STATE_CODE
# re-evaluate same line
# continues automatically
A continuación se muestra una forma muy sencilla de emular un bucle do- while:
condition = True
while condition:
# loop body here
condition = test_loop_condition()
# end of loop
Las características clave de un bucle do- while son que el cuerpo del bucle siempre se ejecuta al menos una vez y que la condición se evalúa en la parte inferior del cuerpo del bucle. La estructura de control que se muestra aquí logra ambas cosas sin necesidad de excepciones ni declaraciones de interrupción. Introduce una variable booleana adicional.