¿Cómo emular un bucle do- while?

Resuelto grigoryvp asked hace 15 años • 22 respuestas

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
grigoryvp avatar Apr 13 '09 13:04 grigoryvp
Aceptado

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
Tom avatar Apr 13 '2009 06:04 Tom

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.

powderflask avatar Mar 14 '2010 00:03 powderflask