11

Как эмулировать цикл do-while?

9

Я пытаюсь эмулировать цикл do-while в программе на Python. К сожалению, представленный ниже код не работает так, как я ожидал:

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"

Вместо вывода "1, 2, 3, done", я получаю следующее:

[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', '  File "test_python.py", line 8, in <module>
    s = i.next()
', 'StopIteration
']

Как я могу поймать исключение 'StopIteration' и корректно завершить цикл while?

Пример, почему это может быть необходимо, представлен ниже в псевдокоде.

Состояние автомата:

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
      # Повторно оцениваем ту же строку
      continue
  try :
    s = i.next()
  except StopIteration :
    break

Надеюсь, вы сможете помочь разобраться с этой проблемой.

5 ответ(ов)

13

Я не совсем понимаю, что вы пытаетесь сделать. Вы можете реализовать цикл do-while следующим образом:

while True:
    stuff()
    if fail_condition:
        break

Или так:

stuff()
while not fail_condition:
    stuff()

Зачем вам использовать цикл do-while для печати элементов в списке? Почему бы просто не воспользоваться:

for i in l:
    print(i)
print("done")

Обновление:

Итак, у вас есть список строк? И вы хотите продолжать проходить по нему? Как насчет:

for s in l: 
    while True: 
        stuff() 
        # используйте "break" вместо s = i.next()

Похоже, это близко к тому, что вам нужно? Используя ваш пример кода, это будет выглядеть так:

for s in some_list:
    while True:
        if state == STATE_CODE:
            if "//" in s:
                tokens.add(TOKEN_COMMENT, s.split("//")[1])
                state = STATE_COMMENT
            else:
                tokens.add(TOKEN_CODE, s)
        if state == STATE_COMMENT:
            if "//" in s:
                tokens.append(TOKEN_COMMENT, s.split("//")[1])
                break  # получаем следующую строку s
            else:
                state = STATE_CODE
                # повторная оценка той же строки
                # продолжается автоматически
4

Вот очень простой способ эмулировать цикл do-while:

condition = True
while condition:
    # тело цикла здесь
    condition = test_loop_condition()
# конец цикла

Ключевые особенности цикла do-while заключаются в том, что тело цикла выполняется как минимум один раз, а условие проверяется в конце тела цикла. Представленная конструкция управления достигает этого без необходимости в исключениях или операторах прерывания. Однако она вводит одну дополнительную булеву переменную.

0

Вы можете использовать цикл do...while в Python следующим образом:

while True:
    stuff()
    if not condition():
        break

Также можно создать функцию:

def do_while(stuff, condition):
    while condition(stuff()):
        pass

Однако у этого подхода есть некоторые недостатки:

  1. Он выглядит не очень эстетично.
  2. Условие должно быть функцией с одним параметром, который заполняется результатом вызова stuff(). Это единственная причина, по которой стоит избегать классического цикла while.

На практике использование первого подхода часто предпочтительнее за его простоту и читаемость.

0

Способ, которым я это делал, заключается в следующем...

condition = True
while condition:
     do_stuff()
     condition = (<что-то, что будет возвращать True или False>)

Мне кажется, что это довольно простой подход, и я удивлён, что ещё никто не упомянул его здесь. Это также очевидно можно инвертировать, например:

while not condition:

и так далее.

0

Вы правы, так как данный пример действительно имитирует конструкцию do-while, присущую языкам C и Java. В вашем коде переменная do устанавливается в True, и цикл while выполняется как минимум один раз, что соответствует поведению do-while. Внутри цикла вы можете выполнять необходимые операции и затем обновлять условие. Вот как это выглядит:

do = True
while do:
    # Ваш код
    do = <условие>  # обновление условия для продолжения цикла

Таким образом, структура вашего кода действительно напоминает do-while, так как выполнение блока кода происходит перед проверкой условия. Это хороший подход для имитации этой функциональности в Python.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь