He notado que el siguiente código es legal en Python. Mi pregunta es por qué Hay una razón específica?
n = 5
while n != 0:
print n
n -= 1
else:
print "what the..."
after:.
He notado que el siguiente código es legal en Python. Mi pregunta es por qué Hay una razón específica?
n = 5
while n != 0:
print n
n -= 1
else:
print "what the..."
after:.
Respuestas:
La elsecláusula solo se ejecuta cuando su whilecondición se vuelve falsa. Si se breaksale del ciclo o si se genera una excepción, no se ejecutará.
Una forma de pensarlo es como una construcción if / else con respecto a la condición:
if condition:
handle_true()
else:
handle_false()
es análogo a la construcción de bucle:
while condition:
handle_true()
else:
# condition is false now, handle and go on with the rest of the program
handle_false()
Un ejemplo podría ser lo siguiente:
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 excepto que somethingse omitirá si estás breaken el whilebucle.
La elsecláusula se ejecuta si sale de un bloque normalmente, golpeando la condición del bucle o cayendo del fondo de un bloque try. Se no se ejecuta si breako returnfuera de un bloque, o lanzar una excepción. Funciona no solo para while y para bucles, sino también para probar bloques.
Por lo general, lo encuentra en lugares donde normalmente saldría de un bucle temprano, y salir corriendo al final del bucle es una ocasión inesperada / inusual. Por ejemplo, si está recorriendo una lista buscando un valor:
for value in values:
if value == 5:
print "Found it!"
break
else:
print "Nowhere to be found. :-("
found_it=Falseal comienzo de un bucle, y luego hago un chequeo found_ital final
En respuesta a Is there a specific reason?, aquí hay una aplicación interesante: romper múltiples niveles de bucles.
Así es como funciona: el bucle externo tiene un descanso al final, por lo que solo se ejecutará una vez. Sin embargo, si el ciclo interno se completa (no encuentra divisor), entonces alcanza la instrucción else y nunca se alcanza la ruptura externa. De esta manera, una ruptura en el bucle interno saldrá de ambos bucles, en lugar de uno solo.
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 whiley forbucles, la elsedeclaración se ejecuta al final, a menos que breakse haya utilizado.
En la mayoría de los casos, hay mejores formas de hacerlo (envolviéndolo en una función o generando una excepción), ¡pero esto funciona!
La cláusula else se ejecuta cuando la condición while se evalúa como falsa.
De la documentación :
La instrucción while se usa para la ejecución repetida siempre que una expresión sea verdadera:
while_stmt ::= "while" expression ":" suite ["else" ":" suite]Esto prueba repetidamente la expresión y, si es verdadera, ejecuta la primera suite; si la expresión es falsa (que puede ser la primera vez que se prueba), el conjunto de la
elsecláusula, si está presente, se ejecuta y el ciclo termina.Una
breakdeclaración ejecutada en el primer conjunto termina el ciclo sin ejecutar elelseconjunto de la cláusula. Unacontinuedeclaración ejecutada en la primera suite omite el resto de la suite y vuelve a probar la expresión.
Mi respuesta se centrará en CUÁNDO podemos usar while / for-else.
A primera vista, parece que no hay diferencia cuando se usa
while CONDITION:
EXPRESSIONS
print 'ELSE'
print 'The next statement'
y
while CONDITION:
EXPRESSIONS
else:
print 'ELSE'
print 'The next statement'
Porque la print 'ELSE'declaración parece siempre ejecutada en ambos casos (ambos cuando el whileciclo finalizó o no se ejecutó).
Entonces, solo es diferente cuando la declaración print 'ELSE'no se ejecutará. Es cuando hay un breakbloque de código dentro dewhile
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
Si difiere 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 no está en esta categoría, porque tiene el mismo efecto para los dos casos anteriores.
el aumento de excepción tampoco causa diferencia, porque cuando aumenta, donde se ejecutará el siguiente código está en el controlador de excepción (excepto el bloque), el código en la elsecláusula o justo después de la whilecláusula no se ejecutará.
Sé que esta es una pregunta vieja pero ...
Como dijo Raymond Hettinger, debería llamarse en while/no_breaklugar de while/else.
Me resulta fácil entender y si nos fijamos en este fragmento.
n = 5
while n > 0:
print n
n -= 1
if n == 2:
break
if n == 0:
print n
Ahora, en lugar de verificar la condición después del ciclo while, podemos intercambiarlo elsey deshacernos de esa comprobación.
n = 5
while n > 0:
print n
n -= 1
if n == 2:
break
else: # read it as "no_break"
print n
Siempre lo leo while/no_breakpara entender el código y esa sintaxis tiene mucho más sentido para mí.
La cláusula else solo se ejecuta cuando la condición while se vuelve falsa.
Aquí hay unos ejemplos:
Ejemplo 1: Inicialmente, la condición es falsa, por lo que se ejecuta la cláusula else .
i = 99999999
while i < 5:
print(i)
i += 1
else:
print('this')
SALIDA:
this
Ejemplo 2: El mientras condición i < 5 nunca se convirtió en falso, porque i == 3rompe el bucle, por lo demás-cláusula no se ha ejecutado.
i = 0
while i < 5:
print(i)
if i == 3:
break
i += 1
else:
print('this')
SALIDA:
0
1
2
3
Ejemplo 3: El mientras que la condición i < 5 se convirtió en falso cuando ifue 5, por lo demás-cláusula fue ejecutado.
i = 0
while i < 5:
print(i)
i += 1
else:
print('this')
SALIDA:
0
1
2
3
4
this
La else:instrucción se ejecuta cuando y solo cuando el ciclo while ya no cumple su condición (en su ejemplo, cuando n != 0es falso).
Entonces la salida sería esta:
5
4
3
2
1
what the...
El otro se ejecuta si el bucle while no se rompió.
Me gusta pensar en ello con una metáfora de "corredor".
El "más" es como cruzar la línea de meta, sin importar si comenzó al principio o al final de la pista. "else" solo no se ejecuta si se interrumpe en algún punto intermedio.
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.
Los principales casos de uso son el uso de esta ruptura de bucles anidados o si desea ejecutar algunas declaraciones solo si el bucle no se rompió en alguna parte (piense en romper como una situación inusual).
Por ejemplo, el siguiente es un mecanismo sobre cómo salir de un bucle interno sin usar variables o try / catch:
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
El mejor uso de la construcción 'while: else:' en Python debería ser si no se ejecuta ningún ciclo en 'while', entonces se ejecuta la instrucción 'else'. La forma en que funciona hoy no tiene sentido porque puede usar el siguiente código con los mismos resultados ...
n = 5
while n != 0:
print n
n -= 1
print "what the..."
elsebloque no se ejecutará si está dejando de usar el bucle breako la returnpalabra clave. En su ejemplo, printse ejecutará también si el ciclo ha finalizado con el breakcomando.
Es útil para la interacción social.
while (Date != "January 1st"):
time.sleep(1)
else:
print("Happy new year!")
elseaquí? El código hace exactamente lo mismo sin él.
breakdurante su cuenta regresiva, no usarlo elsele hará decir "¡Feliz año nuevo!" al instante, lo que no tiene ningún sentido.
break"? No hay breaken el código.
elsepara este uso había sido una muy mala idea, y que no harían más de esto.