Операторы break и continue, слово else в циклах

Оператор break

А теперь допустим, что нам нужно вывести для введённого числа его минимальный делитель, отличный от единицы (делитель - это такое число, на которое данное делится без остатка, например, для числа 15 делителями являются 1, 3, 5, 15).

Пользуясь лишь знаниями, полученными ранее, можно написать следующий код для решения данной задачи:

1
2
3
4
5
6
7
number = int(input())
divisor = 2
while divisor <= number:
    if number % divisor == 0:
        print(divisor)
        divisor = number + 1
    divisor = divisor + 1
Любители математики и быстродействия программ могут заметить, что достаточно проверять делители только до квадратного корня, так как числа, большие квадратного корня числа, не являются его минимальными делителями. Этот подход мы ещё применим, а пока что будем проверять все делители.

Разберем снова построчно:

  1. number = int(input()) - здесь мы с помощью input считываем ввод пользователя, а затем с помощью функции int преобразуем в целое число
  2. divisor = 2 - наш потенциальный делитель. Единица не подходит по условию, начинаем с 2.
  3. while divisor <= number: - до тех пор, пока делитель меньше либо равен введённому ранее числу, выполнить блок 4-7
  4. if number % divisor == 0: - если остаток от деления числа на наш делитель равен нулю (т.е. это и есть делитель)
  5. print(divisor) - напечатать делитель
  6. divisor = number + 1 - а вот здесь объясню далее
  7. divisor = divisor + 1 - увеличить divisor на 1

Так что же за магия в строке 6? Мы присваиваем divisor значение, которое на следующей же итерации цикла точно станет ложным. Так мы гарантированно напечатаем только один (и он же минимальный) делитель числа.

Какие сложности возникают при таком подходе?

  • Зависимость от условия. Если мы захотим изменить условие цикла, возможно, всё сломается. Если условие более сложное, то более сложное выражение должно быть в строке 6.
  • Всё после строки 6 и до конца цикла будет выполнено. divisor станет равным, на самом деле, number + 2. Сейчас это неважно, в более масштабных программах это может оказаться важным.

Понятное дело, так никто не делает. Для досрочного выхода из цикла есть оператор break.

1
2
3
4
5
6
7
number = int(input())
divisor = 2
while divisor <= number:
    if number % divisor == 0:
        print(divisor)
        break
    divisor = divisor + 1

Код весь тот же самый. Единственное отличие в том, что в строке 6 теперь только оператор break. Что он делает? Оператор break инструктирует выйти из ближайшего цикла (while, или for, который мы разберём позднее).

Оператор continue

Оператор continue инструктирует пропустить остаток тела цикла и перейти снова к условию.

Допустим, та же задача: вывести минимальный делитель числа, отличный от единицы. Как это можно решить с помощью continue:

1
2
3
4
5
6
7
8
number = int(input())
divisor = 1
while divisor < number:
    divisor = divisor + 1
    if number % divisor != 0:
        continue
    print(divisor)
    break

Что поменялось:

  1. divisor = 1
  2. while divisor < number:
  3. divisor = divisor + 1 - увеличиваем divisor на 1 в начале цикла, поскольку continue пропустит всё оставшееся тело цикла, включая увеличение переменной, что приведёт к бесконечному циклу. По этой же причине мы начинаем не с 2, а с 1, и в условии у нас меньше, а не (меньше либо равно). По сути, весь оставшийся блок цикла работает с переменной, УЖЕ увеличенной на 1.
  4. if number % divisor != 0: - если остаток от деления числа на наш делитель НЕ равен нулю
  5. continue - пропустить строки 7-8, и перейти к строке 3
  6. print(divisor) - напечатать делитель
  7. break - выйти из цикла
На самом деле, continue гораздо чаще используется в цикле for (который будет рассмотрен позднее), чем в цикле while. Пример выше получился немного высосанным из пальца, и дан исключительно в образовательных целях.

While - else

Слово else, примененное в цикле for или while, проверяет, был ли произведен выход из цикла инструкцией break, или же "естественным" образом. Блок инструкций внутри else выполнится только в том случае, если выход из цикла произошел без помощи break.

Допустим, нам нужно не только вывести минимальный делитель числа, отличный от единицы. Но ещё, если этот минимальный делитель равен самому числу, то написать, что оно простое.

Как это можно сделать без while - else:

1
2
3
4
5
6
7
8
9
number = int(input())
divisor = 2
while divisor <= number:
    if number % divisor == 0:
        print(divisor)
        if divisor == number:
            print("Число простое")
        break
    divisor = divisor + 1

Здесь в строках 6 и 7 мы записали ещё одно условие: если делитель оказался равен самому числу, то напечатаем ещё и "Число простое".

А теперь вспомним, что достаточно проверять не все делители, а только делители до квадратного корня из числа. И если делителей до квадратного корня из числа нет, то число простое (а минимальный делитель, соответственно - само число).

Условие в строках 6 и 7 становится бесполезным, но здесь на помощь нам приходит слово else:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
number = int(input())
divisor = 2
while divisor <= number ** 0.5:
    if number % divisor == 0:
        print(divisor)
        break
    divisor = divisor + 1
else:
    print(number)
    print("Число простое")

Если мы вышли из цикла с помощью break (перед которым мы напечатали делитель), то больше ничего не выводим. Иначе - выполняется блок else, в котором печатаем само число и строку "Число простое".

Слово else под циклом не имеет ничего общего с выражением if - else! То, к какому блоку относится else, указывается уровнем отступа.