Eu preciso emular um loop do-while em um programa Python. Infelizmente, o seguinte código simples não 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"
Em vez de "1,2,3, done", ele imprime a seguinte saída:
[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', ' File "test_python.py", line 8, in <module>
s = i.next()
', 'StopIteration
']
O que posso fazer para capturar a exceção 'stop iteration' e interromper um loop while corretamente?
Um exemplo de por que tal coisa pode ser necessária é mostrado abaixo como pseudocódigo.
Máquina de estado:
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
fonte
fonte
s=i.next()
vez de Nenhum e possivelmente faria algum trabalho inicial, em vez de apenas tornar inútil sua primeira passagem pelo loop.Respostas:
Não tenho certeza do que você está tentando fazer. Você pode implementar um loop do-while como este:
Ou:
O que você está tentando usar um loop do while para imprimir as coisas da lista? Por que não usar:
Atualizar:
Então você tem uma lista de linhas? E você quer continuar iterando? E se:
Parece algo próximo do que você gostaria? Com o seu exemplo de código, seria:
fonte
Aqui está uma maneira muito simples de emular um loop do-while:
Os principais recursos de um loop do-while são que o corpo do loop sempre é executado pelo menos uma vez e que a condição é avaliada na parte inferior do corpo do loop. A estrutura de controle mostrada aqui realiza ambos sem a necessidade de exceções ou instruções de interrupção. Ele introduz uma variável booleana extra.
fonte
break
. Especificamente, se houver lógica necessária DEPOIStest_loop_condition()
, que não deva ser executada depois que terminarmos, ela deverá ser envolvidaif condition:
. Aliás,condition
é vago. Mais descritivo:more
ounotDone
.break
em loops e, quando o encontro em código que mantenho, acho que o loop, na maioria das vezes, poderia ter sido escrito sem ele. A solução apresentada é, IMO, a maneira mais clara de representar um fazer enquanto constrói em python.has_no_errors
ouend_reached
(nesse caso, o loop seria iniciadowhile not end_reached
Meu código abaixo pode ser uma implementação útil, destacando a principal diferença entre fazer enquanto vs enquanto Como eu entendo.
Portanto, neste caso, você sempre passa pelo loop pelo menos uma vez.
fonte
while condition or first_pass:
. Entãocondition
é sempre avaliado primeiro e o geralfirst_pass
é avaliado apenas duas vezes (primeira e última iteração). Não se esqueça de inicializarcondition
antes do loop o que quiser.A exceção interromperá o loop, então você também pode lidar com isso fora do loop.
Eu acho que o problema com o seu código é que o comportamento de
break
dentroexcept
não está definido. Geralmentebreak
sobe apenas um nível, por exemplo, obreak
interiortry
vai diretamente parafinally
(se existir) um fora dotry
loop, mas não fora do loop.PEP relacionado: http://www.python.org/dev/peps/pep-3136
Pergunta relacionada: Rompendo loops aninhados
fonte
->
Você pode fazer uma função:
Mas 1) é feio. 2) Condição deve ser uma função com um parâmetro, que deve ser preenchida por coisas (é a única razão para não usar o loop while clássico).
fonte
while True: stuff(); if not condition(): break
é uma ideia muito boa. Obrigado!Aqui está uma solução mais louca de um padrão diferente - usando corotinas. O código ainda é muito semelhante, mas com uma diferença importante; não há condições de saída! A corotina (cadeia de corotinas realmente) apenas para quando você para de alimentá-la com dados.
O código acima coleta todos os tokens como tuplas
tokens
e presumo que não haja diferença entre.append()
e.add()
no código original.fonte
A maneira que eu fiz isso é a seguinte ...
Parece-me a solução simplista, estou surpreso por ainda não o ter visto aqui. Obviamente, isso também pode ser invertido para
etc.
fonte
para um loop do - while contendo instruções try
alternativamente, quando não há necessidade da cláusula 'finalmente'
fonte
fonte
stuff
que seja uma função ou que o corpo do código seja repetido.while condition:
porqueis True
está implícito.condition
depender de alguma variável interna destuff()
, porque essa variável não está definida naquele momento.Corte rápido:
Use assim:
fonte
Por que você não faz
?
fonte
Veja se isso ajuda:
Defina um sinalizador dentro do manipulador de exceções e verifique-o antes de trabalhar no s.
fonte
while not flagBreak:
e removendo oif (flagBreak) : break
.flag
Evito variáveis nomeadas --Não consigo inferir o que um valor Verdadeiro ou Falso significa. Em vez disso, usedone
ouendOfIteration
. O código se transformawhile not done: ...
.Se você estiver em um cenário em que está fazendo um loop enquanto um recurso não está disponível ou é algo semelhante que gera uma exceção, você pode usar algo como
fonte
Para mim, um loop while típico será algo como isto:
Eu também poderia incluir um loop for..l no loop while, se a situação o justificar, por loop através de outro conjunto de condições.
fonte