Как эмулировать цикл do-while?
Я пытаюсь эмулировать цикл 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 ответ(ов)
Я не совсем понимаю, что вы пытаетесь сделать. Вы можете реализовать цикл 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
# повторная оценка той же строки
# продолжается автоматически
Вот очень простой способ эмулировать цикл do-while:
condition = True
while condition:
# тело цикла здесь
condition = test_loop_condition()
# конец цикла
Ключевые особенности цикла do-while заключаются в том, что тело цикла выполняется как минимум один раз, а условие проверяется в конце тела цикла. Представленная конструкция управления достигает этого без необходимости в исключениях или операторах прерывания. Однако она вводит одну дополнительную булеву переменную.
Вы можете использовать цикл do...while
в Python следующим образом:
while True:
stuff()
if not condition():
break
Также можно создать функцию:
def do_while(stuff, condition):
while condition(stuff()):
pass
Однако у этого подхода есть некоторые недостатки:
- Он выглядит не очень эстетично.
- Условие должно быть функцией с одним параметром, который заполняется результатом вызова
stuff()
. Это единственная причина, по которой стоит избегать классического циклаwhile
.
На практике использование первого подхода часто предпочтительнее за его простоту и читаемость.
Способ, которым я это делал, заключается в следующем...
condition = True
while condition:
do_stuff()
condition = (<что-то, что будет возвращать True или False>)
Мне кажется, что это довольно простой подход, и я удивлён, что ещё никто не упомянул его здесь. Это также очевидно можно инвертировать, например:
while not condition:
и так далее.
Вы правы, так как данный пример действительно имитирует конструкцию do-while
, присущую языкам C и Java. В вашем коде переменная do
устанавливается в True
, и цикл while
выполняется как минимум один раз, что соответствует поведению do-while
. Внутри цикла вы можете выполнять необходимые операции и затем обновлять условие. Вот как это выглядит:
do = True
while do:
# Ваш код
do = <условие> # обновление условия для продолжения цикла
Таким образом, структура вашего кода действительно напоминает do-while
, так как выполнение блока кода происходит перед проверкой условия. Это хороший подход для имитации этой функциональности в Python.
Почему используется string.join(list), а не list.join(string)?
Создание словаря с помощью генератора словарей
Как получить полный путь к директории текущего файла?
UnicodeDecodeError: Кодек 'charmap' не может декодировать байт X в позиции Y: символ отображается как <неопределённый>
Найти все файлы с расширением .txt в директории на Python