В процессе разработки программ часто возникает необходимость многократно выполнять одни те же действия. Например, представим, что мы управляем роботом на клетчатом поле, и за одно действие можем переместить его только на одну клетку. Чтобы сдвинуть его на 3 клетки, нам придется 3 раза повторить команду перемещения:

step = 0
step += 1
print(f"Шагов сделано: {step}") 
# Вывод: Шагов сделано: 1
step += 1
print(f"Шагов сделано: {step}")
# Вывод: Шагов сделано: 2
step += 1
print(f"Шагов сделано: {step}")
# Вывод: Шагов сделано: 3

Но что, если нужно переместить робота на 100 или даже 1000 клеток? Повторять одну и ту же команду столько раз достаточно утомительно. Именно для таких ситуаций в программировании используются циклы – специальные конструкции, позволяющие многократно повторять определенный фрагмент кода, называемый телом цикла. Они существенно упрощают решение задач, связанных с многократным выполнением одинаковых действий.

Цикл со счетчиком for и функция range()

Цикл for предназначен для перебора элементов в последовательности, поэтому чаще всего его используют в сочетании со встроенной функцией range(), генерирующую последовательность целых чисел:

for переменная in range(старт, стоп, шаг):
    тело_цикла

Здесь переменная – это счетчик, который на каждой итерации цикла принимает следующее значение из последовательности, генерируемой функцией range(). Внутри блока тело_цикла находятся инструкции, которые выполняются указанное количество раз.

Робот Кеша читает

Термин «итерация» произошёл от латинского слова iteratio, означающего «повторение». Поэтому итерация подразумевает процесс повторного выполнения одной и той же операции. Например, если вы готовите омлет и взбиваете яйца венчиком, то каждое движение венчика – одна итерация процесса взбивания.

Функция range()

Функция range() возвращает объект, создающий последовательность целых чисел по требованию (в цикле for).

Функция

range(start, stop, step)

Описание

Возвращает последовательность целых чисел от start до stop (не включительно) с шагом step

Параметры

  • stop – число, на котором последовательность заканчивается. При этом само это значение в последовательность не входит


Необязательные параметры:

  • start – число, с которого начинается последовательность, по умолчанию start=0
  • step – число, задающее шаг изменения последовательности, по умолчанию step=1

Возвращаемое значение

Объект, создающий последовательность целых чисел

При указании одного обязательного параметра stop функция range(stop) создаёт последовательность чисел от 0 до stop - 1:

for i in range(10):
    print(i, end=" ")
# Вывод: 0 1 2 3 4 5 6 7 8 9

При указании двух параметров start и stop функция range(start, stop) создаёт последовательность чисел от start до stop - 1:

for i in range(2, 8):
    print(i, end=" ")
# Вывод: 2 3 4 5 6 7

При указании всех трёх параметров start, stop и step функция range(start, stop, step) создаёт последовательность чисел от start до stop - 1 с шагом step:

for i in range(2, 11, 2):
    print(i, end=" ")
# Вывод: 2 4 6 8 10
Обратите внимание, что число stop не входит в последовательность чисел, создаваемую функцией range(), в то время как с числа start эта последовательность начинается.
Робот Кеша предупреждает

Все параметры функции range() должны быть целыми числами. При этом они могут быть как положительными, так и отрицательными:

for i in range(-6, 9, 2):
    print(i, end=" ")
# Вывод: -6 -4 -2 0 2 4 6 8

Если шаг step отрицательный, то создается убывающая последовательность, поэтому важно соблюдать условие start > stop:

for i in range(5, 0, -1):
    print(i, end=" ")
# Вывод: 5 4 3 2 1

Перебор чисел из последовательности в цикле for

Теперь, используя цикл for и функцию range(), перепишем программу управления роботом и переместим его сразу на 5 шагов:

for i in range(1, 6):
    print(f"Шагов сделано: {i}")

В результате на экран 5 раз будет выведено сообщение о количестве сделанных шагов без необходимости 5 раз писать функцию print():

Шагов сделано: 1
Шагов сделано: 2
Шагов сделано: 3
Шагов сделано: 4
Шагов сделано: 5

Здесь вывод каждой строки на экран соответствует одному выполнению тела цикла, то есть было совершено 5 итераций.

Цикл с предусловием while

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

while условие:
    тело_цикла

Этот цикл также называют циклом с предусловием, так как он продолжает работу, пока условие истинно (True), и останавливается, когда оно становится ложным (False).

Давайте напишем программу, которая, как эхо, повторяет сообщения пользователя до тех пор, пока он не введет специальную фразу для завершения:

message = input("Скажите что-нибудь:")
while message != "Хватит за мной повторять!":
    print(message)
    message = input()
print("Больше не буду")
# Ввод: Скажите что-нибудь: Привет!
# Вывод: Привет!
# Ввод: Скажите что-нибудь: Как дела?
# Вывод: Как дела?
# Ввод: Скажите что-нибудь: Хватит за мной повторять!
# Вывод: Больше не буду

В этом примере программа запрашивает у пользователя ввод строки. До тех пор, пока введённая строка не совпадает со строкой "Хватит за мной повторять!", программа выводит на экран введенное сообщение и снова просит ввести новую строку.

Бесконечный цикл while

Важно обеспечить выполнимость условия в цикле while, так как иначе он будет выполняться бесконечно, что может привести к зависанию программы:

i = 0
while i >= 0:
    i += 1
    print(i)
# Вывод: 1
# Вывод: 2
...

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

Однако бесконечные циклы иногда бывают полезными, например, для ожидания определенного события или обработки потока данных.

Бесконечный цикл можно специально создать с помощью конструкции while True:

while True:
    print("Я хочу сыграть с тобой в игру...")
# Вывод: Я хочу сыграть с тобой в игру...
# Вывод: Я хочу сыграть с тобой в игру...
...

Этот цикл будет бесконечно выводить сообщение на экран. Однако, на практике в таких циклах обычно предусматривается условие выхода с помощью оператора прерывания break.

Оператор прерывания цикла break

Оператор break используется для досрочного завершения цикла, независимо от того, были ли обработаны все элементы последовательности или выполнилось ли условие завершения самого цикла. Часто оператор break применяют в бесконечных циклах while, чтобы обеспечить выход из цикла при наступлении некоторого события.

Давайте рассмотрим игру, в которой первый пользователь загадывает число, а второй пытается его угадать. Игра заканчивается, когда число угадано:

answer = int(input("Загадай число: "))
steps = 0
while True:
    steps += 1
    guess = int(input("Попробуй угадать число: "))
    if guess < answer:
        print("Загаданное число больше!")
    elif guess > answer:
        print("Загаданное число меньше!")
    else:
        print("Поздравляем! Вы выиграли!")
        break
print(f"Количество попыток: {steps}")
# Ввод: Загадай число: 10
# Ввод: Попробуй угадать число: 5
# Вывод: Загаданное число больше!
# Ввод: Попробуй угадать число: 10
# Вывод: Поздравляем! Вы выиграли!

Здесь первый пользователь загадывает и вводит число, которое присваивается переменной answer. Переменная steps предназначена для подсчёта количества попыток.

В бесконечном цикле while True на каждой итерации второму пользователю предлагается ввести предположение guess. Затем введённое число сравнивается с загаданным:

  • Если guess < answer, то выводится подсказка "Загаданное число больше!".
  • Если guess > answer, то выводится подсказка "Загаданное число меньше!".
  • Если guess == answer, то выводится поздравление, и цикл досрочно завершается с помощью оператора break.

При выходе из цикла с помощью break дальнейшие инструкции внутри цикла не выполняются, и управление передается на первую строку кода, следующую за циклом.

Оператор пропуска итерации в цикле continue

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

Допустим, нам нужно вывести на экран все числа от 1 до 50, кроме тех, которые делятся на 2 или на 3 без остатка:

for i in range(1, 51):
    if i % 2 == 0 or i % 3 == 0:
        continue
    print(i, end=" ")
# Вывод: 1 5 7 11 13 17 19 23 25 29 31 35 37 41 43 47 49

Здесь в цикле for перебираются все числа от 1 до 50 включительно. Для каждого числа проверяется, делится ли оно на 2 или на 3 без остатка:

  • Если условие выполняется, текущая итерация прерывается оператором continue, и управление возвращается обратно в начало цикла для следующей итерации.
  • Если число не делится без остатка на 2 или 3, оно выводится на экран.

Блок кода после завершения цикла else

Циклы for и while в Python могут содержать необязательный блок else, который выполняется, если цикл был завершён естественным образом, а не прерван оператором break.

В цикле for блок else выполняется, если все элементы последовательности были обработаны:

for i in range(1, 4):
    print(i, end=" ")
else:
    print("Цикл завершился")
# Вывод: 1 2 3 Цикл завершился

В цикле while блок else выполняется, если условие стало ложным:

i = 1
while i < 4:
    print(i, end=" ")
    i += 1
else:
    print("Цикл завершился")
# Вывод: 1 2 3 Цикл завершился

Вложенные циклы

Внутри одного цикла можно располагать другие циклы. Такие конструкции называются вложенными циклами и могут применяться для выполнения сложных задач.

Одним из классических примеров использования вложенных циклов является вывод таблицы умножения:

for i in range(1, 10):
    for j in range(1, 10):
        print(i * j, end="\t")
    print()

Здесь внешний цикл проходит по строкам таблицы – по значениям переменной i. Для каждого значения i запускается внутренний цикл.
Внутренний цикл проходит по столбцам таблицы – по переменной j. Для каждого значения j вычисляется произведение i * j, которое выводится на экран.

В результате на экран будет выведена таблица умножения:

1       2       3       4       5       6       7       8       9
2       4       6       8       10      12      14      16      18
3       6       9       12      15      18      21      24      27
4       8       12      16      20      24      28      32      36
5       10      15      20      25      30      35      40      45
6       12      18      24      30      36      42      48      54
7       14      21      28      35      42      49      56      63
8       16      24      32      40      48      56      64      72
9       18      27      36      45      54      63      72      81

Тот же результат можно получить с использованием вложенного цикла while:

i, j = 1, 1
while i < 10:
    while j < 10:
        print(i * j, end="\t")
        j += 1
    print()
    i += 1
    j = 1

Здесь переменным i и j присваиваются начальные значения 1. Во внешнем цикле проверяется условие i < 10, и если оно выполняется, то запускается внутренний цикл.
Во внутреннем цикле проверяется условие j < 10, и если оно выполняется, вычисляется произведение i * j, которое выводится на экран.
После завершения внутреннего цикла, переменная i увеличивается на 1, а переменная j сбрасывается до 1 для новой строки. Снова проверяется условие i < 10.

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

Примеры

Пример 1. Обратный отсчет при старте ракеты

Программа отсчитывает время до запуска ракеты, а затем объявляет о старте:

for count in range(10, 0, -1):
    print(count, end=", ")

print("пуск!")

Вывод:

10, 9, 8, 7, 6, 5, 4, 3, 2, 1, пуск!

Пример 2. Авторизация с ограниченным числом попыток

Система авторизации блокирует вход после 3 неудачных попыток ввода пароля:

# Исходные данные
correct_password = "qwerty123"  # Правильный пароль
attempts = 3  # Количество попыток
 
# 3 попытки в цикле while
while attempts > 0:
    password = input("Введите пароль: ")
    if password == correct_password:
        print("Доступ разрешён")
        break  # Досрочное завершение цикла
    attempts -= 1
    print(f"Неверно! Осталось попыток: {attempts}")
else:  # Выполняется, если цикл не был прерван оператором break
    print("Доступ заблокирован. Обратитесь в поддержку.")

Вывод:

Введите пароль: qwerty
Неверно! Осталось попыток: 2
Введите пароль: qwerty123
Доступ разрешён

Пример 3. Таблица символов Юникода

Программа для кодирования символов выводит на экран часть таблицы вывести часть таблицы символов Юникода, показывая числовой код и соответствующий символ для определенного диапазона:

# Начинаем с 'A' (65) и заканчиваем после 'Y' (89) с шагом 5 символов
for row_start_code in range(65, 90, 5):
    for offset in range(5):  # 5 символов в каждой строке
        current_code = row_start_code + offset
        print(f"{current_code}: '{chr(current_code)}'", end="\t")
    print()  # Переход на новую строку после каждой группы из 5 символов

Вывод:

65: 'A' 66: 'B' 67: 'C' 68: 'D' 69: 'E'
70: 'F' 71: 'G' 72: 'H' 73: 'I' 74: 'J'
75: 'K' 76: 'L' 77: 'M' 78: 'N' 79: 'O'
80: 'P' 81: 'Q' 82: 'R' 83: 'S' 84: 'T'
85: 'U' 86: 'V' 87: 'W' 88: 'X' 89: 'Y'

Итоги

  • Цикл – это конструкция для многократного выполнения одного и того же фрагмента кода (тела цикла).
  • Цикл for используется для перебора элементов в последовательности. Его часто применяют с функцией range(), которая генерирует последовательность целых чисел.
  • Цикл while используется, когда точное количество повторений заранее неизвестно, но есть условие выхода из цикла.
  • Конструкция while True создаёт бесконечный цикл.
  • Оператор break используется для досрочного завершения цикла.
  • Оператор continue используется для пропуска оставшейся части текущей итерации цикла.
  • Блок else после циклов for и while выполняется, если цикл был завершён естественным образом (для for – все элементы обработаны, для while – условие стало ложным).
  • Вложенные циклы – это циклы, расположенные внутри других циклов.

Задания для самопроверки

1. Выведите на экран следующие последовательности чисел:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
10, 14, 18, 22, 26
20, 19, 18, 17, 16, 15
for i in range(11):
    print(i, end=" ")
print()  # Для перевода на новую строку
for i in range(10, 27, 4):
    print(i, end=" ")   
print()  # Для перевода на новую строку   
for i in range(20, 14, -1):
    print(i, end=" ")

2. Запросите у пользователя целое число n > 1 и выведите на экран наименьшее число, на которое оно делится без остатка и отличное от единицы.

Пример входных данных

Пример выходных данных

17

17

123

3

55

5

n = int(input())
divider = n
for i in range(2, n + 1):
    if n % i == 0:
        divider = i
        break  
print(divider)

3. Запрашивайте у пользователя ввод чисел до тех пор, пока не будет введено первая строка, не являющаяся числом. После этого вычислите и выведите на экран сумму введённых чисел.

Пример входных данных

Пример выходных данных

1

2

3

Нет

6

20

21

9

Хватит

50

100

200

Стоп

300

n = 0
summa = 0
while n != "Стоп" and n != "Хватит":
    summa += int(n)
    n = input()    
print(summa)

4. Запрашивайте у пользователя ввод чисел до тех пор, пока не будет введено первое нечётное число. После этого выведите на экран последнее введённое число. Если первое введённое число было нечётным, то выведите 0.

Пример входных данных

Пример выходных данных

2
4
7

4

20
22
25

22

1

0

n = int(input())
even_n = 0
while n % 2 == 0:
    even_n = n
    n = int(input()) 
print(even_n)

5. Запросите у пользователя целое число n > 1 и выведите на экран на одной строке через пробел все нечётные числа от 1 до n включительно, кроме чисел от 11 до 21 включительно.

Пример входных данных

Пример выходных данных

34

1 3 5 7 9 11 21 23 25 27 29 31 33

14

1 3 5 7 9

25

1 3 5 7 9 23 25

n = int(input())
for i in range(1, n + 1, 2):
    if 11 <= i <= 21:
        continue
    print(i, end=" ")

6. Запросите у пользователя целое число n > 1 и строку s. Выведите на экран треугольник с высотой n из строк s.

Пример входных данных

Пример выходных данных

3
*

*
* *
* * *

5
#

#
# #
# # #
# # # #
# # # # #

6
снег

снег
снег снег
снег снег снег
снег снег снег снег
снег снег снег снег снег
снег снег снег снег снег снег

n = int(input())
s = input()
for i in range(n):
    for j in range(i, -1, -1):
        print(s, end=" ")
    print()  # Для перевода на новую строку