В этом параграфе мы рассмотрим синтаксис, назначение и примеры использования циклов while и for.

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

Пользователь вводит пароль, а система разрешит вход, если пароль верный, а если нет — попросит ввести его снова. Для реализации программы недостаточно использовать только условный оператор, так как он позволит провести проверку только один раз. На помощь нам приходит цикл — он позволяет выполнять код многократно:

saved_pwd = "right_password"
pwd = input("Введите пароль для входа: ")
while pwd != saved_pwd:
    pwd = input("Введите пароль для входа: ")
print("Пароль верный. Вход разрешён.")

В программе применяется цикл while, в котором используется условие для проверки продолжения цикла. Другими словами, пока выполняется условие, цикл продолжает работать. Условие необходимо для того, чтобы цикл не был бесконечным. Тело цикла — это код, который будет выполняться многократно. Синтаксис языка Python требует, чтобы тело цикла записывалось с отступом в четыре пробела (использование табуляций крайне не рекомендуется).

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

В предыдущем примере мы можем вообще обойтись без переменной pwd, так как она используется только в проверке условия продолжения цикла:

saved_pwd = "right_password"
while input("Введите пароль для входа: ") != saved_pwd:
    pass
print("Пароль верный. Вход разрешён.")

Обратите внимание, что внутри тела цикла была использована пустая инструкция pass.

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

В Python версии 3.8 появился моржовый оператор (walrus operator). Он записывается как := и позволяет одновременно вычислить выражение, присвоить результат переменной и вернуть это значение, например в условие.

Давайте напишем программу, которая будет здороваться со всеми людьми, чьи имена введёт пользователь. Сигнал для остановки — ввод строки «СТОП»:

name = input("Введите имя: ")
while name != "СТОП":
    print(f"Привет, {name}!")
    name = input("Введите имя: ")
print("Программа завершена.")

А теперь перепишем эту программу с использованием моржового оператора:

while (name := input("Введите имя: ")) != "СТОП":
    print(f"Привет, {name}!")
print("Программа завершена.")

Благодаря моржовому оператору из программы были убраны строки, в которых считывалось имя первый раз до цикла, а также в теле цикла. Теперь имя считывается только непосредственно на этапе проверки, выполняется ли условие продолжения цикла.

Итак, цикл while обычно применяется в тех случаях, когда заранее не известно, сколько итераций будет выполнено, но известно условие, при котором цикл продолжает работу.

Если количество итераций заранее известно, то предпочтительнее использовать цикл for. Он применяется совместно с итерируемой переменной. Очень часто ей дают имя i и используют в теле цикла, а её значение изменяется на каждой итерации в соответствии с диапазоном, заданным функцией range(). Строго говоря, range() является не функцией, а встроенным типом данных (Built-in Type), представляющим собой последовательность целых чисел. Подробнее про него можно почитать в документации. А мы для простоты изложения будем всё же называть range() функцией.

Функция range() может принимать от одного до трёх целочисленных аргументов:

  • range(n) — возвращает последовательность целых чисел от 0 до n - 1. Например, range(4) вернёт последовательность целых чисел: 0, 1, 2, 3;
  • range(k, n) — возвращает последовательность целых чисел от k до n - 1. Например, range(1, 5) вернёт последовательность целых чисел: 1, 2, 3, 4;
  • range(k, n, s) — возвращает последовательность целых чисел от k до n - 1 с шагом s. Например, range(1, 10, 2) вернёт последовательность целых чисел: 1, 3, 5, 7, 9.

Выведем на экран n целых чисел, начиная с 0 (n вводится пользователем):

n = int(input("Введите количество чисел: "))
for i in range(n):
    print(i)

Результат работы программы:

Введите количество чисел: 5
0
1
2
3
4

Выведем на экран целые числа в диапазоне от k до n - 1 (k, n вводятся пользователем):

k = int(input("Введите начало диапазона: "))
n = int(input("Введите конец (без включения) диапазона: "))
for i in range(k, n):
    print(i)

Результат работы программы:

Введите начало диапазона: 2
Введите конец (без включения) диапазона: 5
2
3
4

Выведем на экран целые чётные числа в диапазоне от 0 до n (n вводится пользователем):

n = int(input("Введите конец диапазона: "))
for i in range(0, n + 1, 2):
    print(i)

Результат работы программы:

Введите конец диапазона: 5
0
2
4

Используя в функции range() отрицательный шаг, можно запустить цикл в обратном порядке:

n = int(input("Введите первое число: "))
for i in range(n, -1, -1):
    print(i)

Результат работы программы:

Введите первое число: 5
5
4
3
2
1
0

Попробуем указать параметры диапазона, в который не попадёт ни одно число. Например, range(1, 5, -1) или range(10, 1, 2). Как можно видеть, ошибка не произойдёт, а функция range() просто вернёт пустую последовательность чисел. Если попытаться пройти в цикле по такой пустой последовательности, то не будет выполнено ни одной итерации:

for i in range(1, 5, -1):
    print(i)

Обратите внимание: изменение значения итерируемой переменной внутри тела цикла не имеет смысла, так как будет перезаписано на следующей итерации очередным значением из диапазона функции range(). Например, следующий код по-прежнему выведет числа от 0 до n - 1, несмотря на изменение значения итерируемой переменной в теле цикла:

n = int(input("Введите n: "))
for i in range(n):
    print(i)
    i = 100

Результат работы программы:

Введите n: 5
0
1
2
3
4

Отмечайте параграфы как прочитанные чтобы видеть свой прогресс обучения

Вступайте в сообщество хендбука

Здесь можно найти единомышленников, экспертов и просто интересных собеседников. А ещё — получить помощь или поделиться знаниями.
Вступить
Сообщить об ошибке
Предыдущий параграф2.2. Условный оператор

Здесь мы поговорим о синтаксисе, назначении и примерах использования условного оператора. А также рассмотрим применение логических операций и некоторые полезные встроенные функции.

Следующий параграф2.4. Вложенные циклы

Тут — разберёмся, что такое вложенные циклы, а также как пользоваться флагами и операторами break и continue.