Notei que o código a seguir é legal no Python. Minha pergunta é por que? Existe um motivo específico?
n = 5
while n != 0:
print n
n -= 1
else:
print "what the..."
after:
.
Notei que o código a seguir é legal no Python. Minha pergunta é por que? Existe um motivo específico?
n = 5
while n != 0:
print n
n -= 1
else:
print "what the..."
after:
.
Respostas:
A else
cláusula é executada apenas quando sua while
condição se torna falsa. Se você break
sair do loop ou se uma exceção for gerada, ela não será executada.
Uma maneira de pensar sobre isso é como uma construção if / else com relação à condição:
if condition:
handle_true()
else:
handle_false()
é análogo à construção de loop:
while condition:
handle_true()
else:
# condition is false now, handle and go on with the rest of the program
handle_false()
Um exemplo pode ser ao longo das linhas de:
while value < threshold:
if not process_acceptable_value(value):
# something went wrong, exit the loop; don't pass go, don't collect 200
break
value = update(value)
else:
# value >= threshold; pass go, collect 200
handle_threshold_reached()
while {} something
exceto que o something
será ignorado se você estiver break
no while
loop.
A else
cláusula é executada se você sair de um bloco normalmente, atingindo a condição de loop ou caindo na parte inferior de um bloco try. É não executada se você break
ou return
fora de um bloco, ou levantar uma exceção. Ele funciona não apenas durante o tempo e para os loops, mas também tenta blocos.
Você normalmente o encontra em lugares onde normalmente você sairia de um loop mais cedo, e correr o final do loop é uma ocasião inesperada / incomum. Por exemplo, se você estiver percorrendo uma lista procurando um valor:
for value in values:
if value == 5:
print "Found it!"
break
else:
print "Nowhere to be found. :-("
found_it=False
no início de um loop e, em seguida, faça um check se found_it
no final
Em resposta Is there a specific reason?
, aqui está uma aplicação interessante: rompendo com vários níveis de loop.
Aqui está como funciona: o loop externo tem uma interrupção no final, portanto, seria executado apenas uma vez. No entanto, se o loop interno for concluído (não encontra divisor), ele alcançará a instrução else e a quebra externa nunca será alcançada. Dessa forma, uma quebra no loop interno sairá dos dois loops, em vez de apenas um.
for k in [2, 3, 5, 7, 11, 13, 17, 25]:
for m in range(2, 10):
if k == m:
continue
print 'trying %s %% %s' % (k, m)
if k % m == 0:
print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
break
else:
continue
print 'breaking another level of loop'
break
else:
print 'no divisor could be found!'
Para ambos while
e for
loops, a else
instrução é executada no final, a menos que tenha break
sido usada.
Na maioria dos casos, existem maneiras melhores de fazer isso (agrupando-o em uma função ou gerando uma exceção), mas isso funciona!
A cláusula else é executada quando a condição while é avaliada como falsa.
A partir da documentação :
A instrução while é usada para execução repetida, desde que uma expressão seja verdadeira:
while_stmt ::= "while" expression ":" suite ["else" ":" suite]
Isso testa repetidamente a expressão e, se for verdade, executa o primeiro conjunto; se a expressão for falsa (que pode ser a primeira vez que é testada), o conjunto da
else
cláusula, se presente, é executado e o loop termina.UMA
break
instrução executada no primeiro conjunto termina o loop sem executar oelse
conjunto da cláusula. Umacontinue
instrução executada no primeiro conjunto ignora o restante do conjunto e volta a testar a expressão.
Minha resposta se concentrará em QUANDO podemos usar while / for-else.
À primeira vista, parece que não há diferenças ao usar
while CONDITION:
EXPRESSIONS
print 'ELSE'
print 'The next statement'
e
while CONDITION:
EXPRESSIONS
else:
print 'ELSE'
print 'The next statement'
Como a print 'ELSE'
instrução parece sempre executada nos dois casos (quando owhile
loop termina ou não é executado).
Então, só é diferente quando a instrução print 'ELSE'
não será executada. É quando existe um break
dentro do bloco de código emwhile
In [17]: i = 0
In [18]: while i < 5:
print i
if i == 2:
break
i = i +1
else:
print 'ELSE'
print 'The next statement'
....:
0
1
2
The next statement
Se for diferente de:
In [19]: i = 0
In [20]: while i < 5:
print i
if i == 2:
break
i = i +1
print 'ELSE'
print 'The next statement'
....:
0
1
2
ELSE
The next statement
return
não está nesta categoria, porque faz o mesmo efeito nos dois casos acima.
O aumento de exceção também não causa diferença, porque quando gera, onde o próximo código será executado está no manipulador de exceções (exceto bloco), o código na else
cláusula ou logo após owhile
cláusula não será executado.
Eu sei que esta é uma pergunta antiga, mas ...
Como Raymond Hettinger disse, deveria ser chamado em while/no_break
vez de while/else
.
Acho fácil entender e se você olhar para este trecho.
n = 5
while n > 0:
print n
n -= 1
if n == 2:
break
if n == 0:
print n
Agora, em vez de verificar a condição após o loop while, podemos trocá-la else
e nos livrar dessa verificação.
n = 5
while n > 0:
print n
n -= 1
if n == 2:
break
else: # read it as "no_break"
print n
Eu sempre o leio while/no_break
para entender o código e essa sintaxe faz muito mais sentido para mim.
A cláusula else é executada apenas quando a condição while se torna falsa.
aqui estão alguns exemplos:
Exemplo 1: Inicialmente a condição é falsa, portanto , a cláusula else é executada.
i = 99999999
while i < 5:
print(i)
i += 1
else:
print('this')
RESULTADO:
this
Exemplo 2: A condição while i < 5
nunca se tornou falsa porque i == 3
quebra o loop; portanto , a cláusula else não foi executada.
i = 0
while i < 5:
print(i)
if i == 3:
break
i += 1
else:
print('this')
RESULTADO:
0
1
2
3
Exemplo 3: A condição while i < 5
se tornou falsa quando i
was 5
, então a cláusula else foi executada.
i = 0
while i < 5:
print(i)
i += 1
else:
print('this')
RESULTADO:
0
1
2
3
4
this
A else:
instrução é executada quando e somente quando o loop while não atender mais a sua condição (no seu exemplo, quandon != 0
for falso).
Portanto, a saída seria esta:
5
4
3
2
1
what the...
Caso contrário, o loop while não quebrou.
Eu meio que gosto de pensar nisso com uma metáfora de 'corredor'.
O "outro" é como cruzar a linha de chegada, não importando se você começou no início ou no final da pista. "else" não é executado apenas se você quebrar em algum lugar.
runner_at = 0 # or 10 makes no difference, if unlucky_sector is not 0-10
unlucky_sector = 6
while runner_at < 10:
print("Runner at: ", runner_at)
if runner_at == unlucky_sector:
print("Runner fell and broke his foot. Will not reach finish.")
break
runner_at += 1
else:
print("Runner has finished the race!") # Not executed if runner broke his foot.
Os principais casos de uso estão usando essa quebra de loops aninhados ou se você deseja executar algumas instruções apenas se o loop não quebrar em algum lugar (pense em quebrar sendo uma situação incomum).
Por exemplo, a seguir está um mecanismo sobre como interromper um loop interno sem usar variáveis ou tentar / capturar:
for i in [1,2,3]:
for j in ['a', 'unlucky', 'c']:
print(i, j)
if j == 'unlucky':
break
else:
continue # Only executed if inner loop didn't break.
break # This is only reached if inner loop 'breaked' out since continue didn't run.
print("Finished")
# 1 a
# 1 b
# Finished
O melhor uso da construção 'while: else:' no Python deve ser se nenhum loop for executado em 'while' e a instrução 'else' será executada. A maneira como funciona hoje não faz sentido, porque você pode usar o código abaixo com os mesmos resultados ...
n = 5
while n != 0:
print n
n -= 1
print "what the..."
else
bloco não será executado se você estiver saindo do loop usando break
ou return
keyword. No seu exemplo, print
será executado também se o loop terminar no break
comando.
É útil para interação social.
while (Date != "January 1st"):
time.sleep(1)
else:
print("Happy new year!")
else
aqui? O código faz exatamente o mesmo sem ele.
break
durante a contagem regressiva, não usar else
o fará dizer "Feliz Ano Novo!" instantaneamente, o que não faz nenhum sentido.
break
"? Não existe break
no código.
else
para esse uso tinha sido uma ideia extremamente ruim e que eles não fariam mais isso.