Я заметил, что следующий код является законным в Python. Почему мой вопрос? Есть ли конкретная причина?
n = 5
while n != 0:
print n
n -= 1
else:
print "what the..."
Я заметил, что следующий код является законным в Python. Почему мой вопрос? Есть ли конкретная причина?
n = 5
while n != 0:
print n
n -= 1
else:
print "what the..."
Предложение else
выполняется только тогда, когда условие while
становится ложным. Если вы break
вышли из цикла или если возникло исключение, оно не будет выполнено.
Один из способов думать об этом - это как конструкция if/else относительно условия:
if condition:
handle_true()
else:
handle_false()
аналогична конструкции цикла:
while condition:
handle_true()
else:
# condition is false now, handle and go on with the rest of the program
handle_false()
Пример может быть в строках:
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()
Предложение else
выполняется, если вы выходите из блока в обычном режиме, попадая в состояние цикла или опуская нижнюю часть блока try. Он не выполняется, если вы break
или return
вышли из блока или вызвали исключение. Он работает не только во время и за циклами, но также и в блоках.
Обычно вы находите его в местах, где обычно вы выходите из цикла раньше, и отключение конца цикла является неожиданным/необычным событием. Например, если вы просматриваете список, ищущий значение:
for value in values:
if value == 5:
print "Found it!"
break
else:
print "Nowhere to be found. :-("
В ответ Is there a specific reason?
, вот одно интересное приложение: разрыв нескольких уровней цикла.
Вот как это работает: внешний цикл имеет разрыв в конце, поэтому он будет выполняться только один раз. Однако, если внутренний цикл завершает (не находит делителя), он достигает выражения else, и внешний разрыв никогда не достигается. Таким образом, разрыв во внутреннем цикле будет выходить из обеих петель, а не только из одного.
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!'
Для while
и for
циклов оператор else
выполняется в конце, если не используется break
.
В большинстве случаев есть лучшие способы сделать это (обертывание его в функцию или создание исключения), но это работает!
Предложение else выполняется, когда условие while принимает значение false.
В документации :
Оператор while используется для повторного выполнения, если выражение истинно:
while_stmt ::= "while" expression ":" suite ["else" ":" suite]
Это многократно проверяет выражение и, если оно истинно, выполняет первый набор; если выражение ложно (это может быть первый раз, когда он протестирован), набор предложения
Операторelse
, если он присутствует, выполняется и цикл завершается.A
break
, выполняемый в первом наборе, завершает цикл без выполнения пакета предложенийelse
. Операторcontinue
, выполняемый в первом пакете, пропускает остальную часть пакета и возвращается к тестированию выражения.
Мой ответ будет посвящен КОГДА мы можем использовать while/for-else.
На первый взгляд кажется, что при использовании
while CONDITION:
EXPRESSIONS
print 'ELSE'
print 'The next statement'
и
while CONDITION:
EXPRESSIONS
else:
print 'ELSE'
print 'The next statement'
Поскольку оператор print 'ELSE'
всегда выполняется в обоих случаях (оба, когда цикл while
завершен или не запущен).
Затем он отличается только тогда, когда оператор print 'ELSE'
не будет выполнен.
Это когда внутри
break
break
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
Если отличается от:
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
не входит в эту категорию, потому что он делает тот же эффект для двух вышеуказанных случаев.
exception raise также не вызывает различия, потому что когда он поднимается, когда следующий код будет выполнен, в обработчике исключений (кроме блока), код в else
или сразу после предложения while
не будет выполняется.
Я знаю, что это старый вопрос, но...
Как сказал Раймонд Хеттингер, его следует называть while/no_break
вместо while/else
.
Мне будет легче понять, если вы посмотрите на этот фрагмент.
n = 5
while n > 0:
print n
n -= 1
if n == 2:
break
if n == 0:
print n
Теперь вместо проверки условия после цикла while мы можем поменять его местами с else
и избавиться от этой проверки.
n = 5
while n > 0:
print n
n -= 1
if n == 2:
break
else: # read it as "no_break"
print n
Я всегда читаю его как while/no_break
, чтобы понять код, и этот синтаксис имеет для меня гораздо больше смысла.
Оператор else:
выполняется тогда и только тогда, когда цикл while больше не удовлетворяет его условию (в вашем примере, когда n != 0
является ложным).
Таким образом, выход будет следующим:
5
4
3
2
1
what the...
Это полезно для социального взаимодействия.
while (Date != "January 1st"):
time.sleep(1)
else:
print("Happy new year!")
Остальное выполняется, если цикл while не прерывался.
Мне нравится думать об этом с метафорой "бегун".
"Остальное" похоже на пересечение финишной линии, независимо от того, начали ли вы в начале или в конце трассы. "else" не выполняется, только если вы прервались где-то посередине.
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.
Основные варианты использования - это использование разрыва вложенных циклов или если вы хотите запускать некоторые операторы только в том случае, если цикл где-то не прерывался (подумайте, что разрыв - это необычная ситуация).
Например, ниже описан механизм выхода из внутреннего цикла без использования переменных или 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
Лучше использовать конструкцию 'while: else:' в Python, если цикл while не выполняется, тогда выполняется инструкция 'else'. То, как он работает сегодня, не имеет смысла, потому что вы можете использовать код ниже с теми же результатами...
n = 5
while n != 0:
print n
n -= 1
print "what the..."