Остальное условие на Python в то время как заявление


321

Я заметил, что следующий код допустим в Python. Мой вопрос почему? Есть ли конкретная причина?

n = 5
while n != 0:
    print n
    n -= 1
else:
    print "what the..."

5
@ detly: Это потому, что большинство людей избегают этой конструкции. :) Я полагаю, что Гвидо упомянул во время процесса Py3k, что, по крайней мере, выбор слова elseдля этого использования был удивительно плохой идеей, и что они больше не будут делать этого.
Николас Найт

5
@ Николас Найт - да, хотя это и заманчиво, но, наверное, это будет то, что я понял на первый взгляд. Любой другой бедняга должен был бы пойти и посмотреть на спецификацию языка, или вернуться назад во времени и задать вопрос здесь, на Sta-heeeeey ...
детально

8
Идея выбора 'else' заключается в том, что эта конструкция предположительно часто используется вместе с 'if X: break' внутри цикла while. Поскольку предложение «else» выполняется, если мы не вырвемся из цикла, оно образует своего рода «else» для «if».
Джонатан Хартли,

12
Они должны переименовать его after:.
naught101

Ответы:


388

Предложение 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()

42
«Предложение else выполняется только тогда, когда ваше условие while становится ложным». Формулировка здесь подразумевает, что ваше состояние while переходит из состояния true в состояние false, а затем выполняется другое. Однако, если while никогда не имеет значения true, предложение else все равно будет выполнено.
user597608

псевдокод. Так что поправьте меня, если я ошибаюсь, но это точно так же, как while {} something за исключением того, что somethingбудет пропущено, если вы breakв whileцикле.
Даниэль Каплан

2
Возможно, наиболее точным псевдокодом будет: while (True) {if (cond) {handle_true (); } else {handle_false (); перерыв; }}
VinGarcia


102

Предложение elseвыполняется, если вы обычно выходите из блока, выполняя условие цикла или опускаясь в нижнюю часть блока try. Он не выполняется, если вы breakлибо returnвышли из блока, либо вырастите исключение. Он работает не только для циклов while и for, но и для блоков try.

Обычно вы обнаруживаете это в тех местах, где обычно вы выходите из цикла раньше, а выход из конца цикла - неожиданный / необычный случай. Например, если вы просматриваете список в поисках значения:

for value in values:
    if value == 5:
        print "Found it!"
        break
else:
    print "Nowhere to be found. :-("

1
На самом деле довольно полезная конструкция для такой вещи. Не знаю, сколько раз я положил found_it=Falseв начале цикла, а затем сделать проверку found_itв конце
Cruncher

42

В ответ на 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был использован.

В большинстве случаев есть лучшие способы сделать это (обернуть это в функцию или вызвать исключение), но это работает!


1
Я не понизил голос, но я думаю, что знаю, почему кто-то сделал. Вы не отвечаете на вопрос, и вы предоставляете 14 строк кода только с 2 строками описания. Если у вас есть отношение к
заданному

1
@BlueEel спасибо за отзыв! Я добавил больше объяснений о коде и пояснил, как это отвечает на вопрос (потому что он отвечает на его часть).
Отметить

Вам удалось поместить свой код в контекст, и, хотя вы не отвечаете на все вопросы, я вижу актуальность сейчас. Я одобрил ваш ответ, так как теперь он полезен для новичков и новичков (как и я в отношении python). - Спасибо, я кое-что узнал.
BlueEel

Мне нравится простое приложение - теперь я понимаю, почему кто-то может его использовать. Хотя я никогда не видел в этом необходимости.
Гейб

В примере показано использование for / else, но вопрос был конкретно о while / else.
Ян Голдби

20

Предложение else выполняется, когда условие while оценивается как false.

Из документации :

Оператор while используется для повторного выполнения, если выражение истинно:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

Это многократно проверяет выражение и, если оно истинно, выполняет первый набор; если выражение ложно (что может быть в первый раз, когда оно проверено), наборelse предложений, если он присутствует, и цикл завершается.

breakЗаявление выполняется в первом набора завершает цикл без выполнения elseнабора Пункта в. continueЗаявление выполняется в первом пакета пропускает оставшуюся часть пакета и возвращается к проверке выражения.


15

Мой ответ будет сосредоточен на том, КОГДА мы можем использовать 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внутри блока кода естьwhile

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 не в этой категории, потому что это делает тот же эффект для двух вышеупомянутых случаев.

Повышение исключения также не вызывает разницы, потому что, когда оно возникает, то, где будет выполняться следующий код, находится в обработчике исключений (кроме блока), код в elseпредложении или сразу после whileпредложения не будет выполнен.


4

Я знаю, что это старый вопрос, но ...

Как сказал Раймонд Хеттингер, его следует называть 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чтобы понять код, и этот синтаксис имеет для меня гораздо больше смысла.


3

Предложение else выполняется только тогда, когда условие while становится ложным.

Вот некоторые примеры:

Пример 1: изначально условие ложно, поэтому выполняется условие else .

i = 99999999

while i < 5:
    print(i)
    i += 1
else:
    print('this')

ВЫВОД:

this

Пример 2: пока условие i < 5 не стало ложным , поскольку i == 3перерывы цикл, поэтому еще придаточный не был выполнен.

i = 0

while i < 5:
    print(i)
    if i == 3:
        break
    i += 1
else:
    print('this')

ВЫВОД:

0
1
2
3

Пример 3: в то время как условие i < 5 становится ложным , когда iбыл 5, так еще придаточный был выполнен.

i = 0

while i < 5:
    print(i)
    i += 1
else:
    print('this')

ВЫВОД:

0
1
2
3
4
this

0

Оператор else:выполняется тогда и только тогда, когда цикл while больше не соответствует своему условию (в вашем примере, когда n != 0false).

Таким образом, результат будет следующим:

5
4
3
2
1
what the...

Я знаю, но этот тип while / else не работает в Java. Я нахожу это довольно интересным, когда выяснил, что это работает в Python. Мне было просто любопытно и хотелось узнать техническую причину.
Иван

6
@Ivan: Дело не в том, что он не работает в Java, а в том, что он не существует в Java. Его можно заставить работать, если кто-то захочет добавить его в язык.
Игнасио Васкес-Абрамс

1
Нет, в то время как False: .. else .. все еще выполняет предложение else. Точнее сказать: еще только не запускается, если цикл прерывается.
Лев Уфимцев

0

Остальное выполняется, если цикл 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

-1

Лучше использовать конструкцию while: else: в Python: если цикл не выполняется в while, тогда выполняется оператор else. То, как это работает сегодня, не имеет смысла, потому что вы можете использовать приведенный ниже код с такими же результатами ...

n = 5
while n != 0:
    print n
    n -= 1
print "what the..."

8
Нет, разница в том, что elseблок не будет выполнен, если вы покидаете цикл, используя ключевое слово breakили return. В вашем примере printбудет выполнено также, если цикл завершился по breakкоманде.
notsure whattodo

2
Вы описываете, как большинство людей хотят, чтобы эта функция работала, а не как она работает на самом деле!
dotancohen

-2

Это полезно для социального взаимодействия.

while (Date != "January 1st"):
    time.sleep(1)
else:
    print("Happy new year!")

2
И какова цель elseздесь? Код делает то же самое без него.
wovano

Если ваши часы и календарь breakво время обратного отсчета, не используя else, заставит вас сказать "С новым годом!" мгновенно, что не имеет никакого смысла.
Гимут

@ Guimote, что вы имеете в виду с "если ваши часы и календарь break"? Там нет breakв коде.
Wovano
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.