Циклы в Python: как работают и какие бывают
Они есть практически в каждом языке программирования, но в Python с ними работать приятнее всего. Как, впрочем, и со всем остальным.


Иллюстрация: Катя Павловская для Skillbox Media
Код в Python обычно выполняется последовательно: первая строка, потом вторая, третья и так далее. Но некоторые конструкции позволяют нарушать этот порядок, чтобы совершать более сложные операции.
Например, циклы выполняют один и тот же блок кода несколько раз. В Python есть два основных вида циклов: while и for. О них и поговорим.
Содержание
- Прерывание цикла: ключевое слово break
- Пропуск части цикла: ключевое слово continue
- Последнее действие в цикле: ключевое слово else
- Бесконечный цикл
- Как сделать аналог do while в Python
- Вложенные циклы в Python
Как работают циклы
Любой цикл состоит из двух обязательных элементов:
- условие — начальный параметр; цикл запустится только при его выполнении и закончится, как только условие перестанет выполняться;
- тело — сама программа, которая выполняется внутри цикла.
Схематически его можно представить так:

В синтаксисе Python в конце строки с условием ставится двоеточие, а всё тело выделяется отступом (табуляцией или четырьмя пробелами).
программа до цикла
условие:
первая строка тела
вторая строка тела
программа после цикла
Цикл while в Python
While — наиболее простой и понятный вид цикла. Его ещё называют циклом с предусловием.
x = 1
while x < 5:
print(x)
x += 1 # Означает то же самое, что x = x + 1
>>> 1
>>> 2
>>> 3
>>> 4
С языка Python на русский программу можно перевести так: «Пока икс меньше пяти, печатай икс и прибавляй к нему единицу».
Но в простоте while кроется и опасность: его легко сделать бесконечным. Например, если в коде выше мы уберём x += 1, то получится вот так:
# Этот код будет выполняться бесконечно
x = 1
while x < 5:
print(x)
Здесь с переменной x ничего не происходит. Она всегда равна единице, поэтому условие цикла никогда не перестанет выполняться. Соответственно, он никогда не завершится.
Чтобы избежать таких ситуаций, при использовании while нужно следить: перестанет ли когда-нибудь выполняться условие? Ещё можно использовать оператор break — о нём мы расскажем чуть позже.
Цикл for в Python
Цикл for программисты используют куда чаще, чем while. Для него мы устанавливаем не условие в чистом виде, а некий массив данных: список, кортеж, строку, словарь, диапазон или любой другой итерируемый объект.
На каждой итерации цикла программа как бы спрашивает: «Остались ли в объекте ещё элементы, по которым я не прошла?»
Допустим, у нас есть список с числами: [14, 101, -7, 0]. Мы можем использовать его вместе с for, чтобы напечатать каждый элемент по отдельности.
num_list = [14, 101, -7, 0]
for number in num_list:
print(number)
>>> 14
>>> 101
>>> -7
>>> 0
Здесь переменная number обновляется при каждом новом витке цикла. Сначала она хранит в себе первый элемент, потом второй, и так — пока список не закончится.
Как и любую другую переменную, мы могли назвать number как угодно. Часто используют буквы i, j и k. Если внутри цикла мы ни разу не обращаемся к этой переменной, то среди питонистов её принято обозначать символом нижнего подчёркивания _.
Функция range()
Когда нужно применить for к числовому промежутку, его можно задать диапазоном. Для этого используют функцию range(). В неё можно передать от одного до трёх аргументов.
Если аргумент один, то сформируется диапазон от нуля до числа, предшествующего значению аргумента.
for i in range(3):
print(i)
>>> 0
>>> 1
>>> 2
Если аргумента два, то сформируется диапазон от значения первого аргумента до числа, предшествующего значению второго аргумента.
for i in range(23, 26):
print(i)
>>> 23
>>> 24
>>> 25
Если аргумента три, то первые два работают, как в прошлом случае. Третий же означает шаг, с которым числа следуют друг за другом.
for i in range(10, 20, 3):
print(i)
>>> 10
>>> 13
>>> 16
>>> 19
Однострочный цикл: генератор списков
Если в теле цикла for выполняется всего одно действие, синтаксис Python позволяет сократить его запись до:
i for i in iterable_object
Это синтаксический сахар, который не добавляет новой функциональности, но влияет на внешний вид кода. Так можно легко и быстро генерировать списки.
num_list = [i for i in range(1, 11)]
print(num_list)
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
В такую конструкцию также можно добавить дополнительное условие. Сделаем генератор, который будет выводить только чётные числа. При этом не будем создавать переменную для получившегося списка, а сразу напечатаем его.
print([i for i in range(1, 11) if i % 2 == 0])
>>> [2, 4, 6, 8, 10]
Конструкция if i % 2 == 0 означает: «если при делении i на 2 остаток равен 0».
С самой переменной i тоже можно проводить операции. Используем предыдущий генератор, но теперь будем выводить не сами чётные числа, а их квадраты.
print([i ** 2 for i in range(1, 11) if i % 2 == 0])
>>> [4, 16, 36, 64, 100]
Главное при таком подходе — сильно не увлекаться. Если код тяжело прочесть и понять (например, когда к i применяется сразу несколько функций и методов и вдобавок задаётся сложное условие), то лучше разбить его на несколько строк. Понятность важнее лаконичности.
Прерывание цикла: ключевое слово break
Бывают случаи, когда нужно завершить цикл принудительно, даже если его условие всё ещё выполняется. В таких случаях используют ключевое слово break.
Возьмём строку Hi, loop! и будем выводить каждый её символ. Если встретим запятую, досрочно завершим цикл.
string = 'Hi, loop!'
for i in string:
if i == ',':
break
print(i)
>>> H
>>> i
Если же в строке запятой не будет, то цикл пройдёт по каждому её символу — и только потом завершится.
string = 'Hi loop!'
for i in string:
if i == ',':
break
print(i)
>>> H
>>> i
>>>
>>> l
>>> o
>>> o
>>> p
>>> !
Пропуск части цикла: ключевое слово continue
Иногда возникает необходимость принудительно начать следующий шаг цикла, пропустив часть строк в его теле. Для таких случаев существует ключевое слово continue.
Возьмём числа от 1 до 10 включительно и выведем из них только те, которые не делятся ни на 2, ни на 3.
for i in range(1, 10):
if i%2 == 0 or i%3 == 0:
continue
print(i)
>>> 1
>>> 5
>>> 7
Как видим, если срабатывает условие if (то есть если число делится на 2 или на 3 без остатка), то оставшаяся часть тела не работает — и i не печатается.
Последнее действие в цикле: ключевое слово else
Обычно ключевое слово else употребляют в связке с if, но у него есть и другое применение. Его можно использовать вместе с while или for. В таком случае else-код выполнится после того, как пройдут все витки цикла.
Если же цикл досрочно прервётся из-за break, то часть программы в else не выполнится.
Вспомним наш код со строкой Hi, loop! и добавим к нему else.
string = 'Hi, loop!'
for i in string:
if i == ',':
break
print(i)
else:
print('Цикл завершился без break')
>>> H
>>> i
В строке была запятая, сработал break — не выполнилось else-условие. Теперь уберём из неё запятую и посмотрим, что получится.
string = 'Hi loop!'
for i in string:
if i == ',':
break
print(i)
else:
print('Цикл завершился без break')
>>> H
>>> i
>>>
>>> l
>>> o
>>> o
>>> p
>>> !
>>> Цикл завершился без break
Цикл прошёл все свои итерации, завершился самостоятельно, и поэтому код в else выполнился. Он также будет работать, если цикл не совершил ни одного витка.
while 1 == 0:
print('Эта строка никогда не выполнится')
else:
print('Цикл завершился без break')
>>> Цикл завершился без break
Бесконечный цикл
Иногда использовать бесконечный цикл может быть хорошей идеей. Например, мы пишем игру: она должна работать до тех пор, пока игрок из неё не выйдет. В этом случае в условии выхода нужно будет прописать break.
Чтобы цикл был бесконечным, его условие должно выполняться всегда. Это можно сделать разными способами.
# Способ №1 — «пока истинно»
while True:
pass # pass — оператор-заглушка, который ничего не делает
Если сделать while False, то цикл, наоборот, никогда не начнётся.
# Способ №2 — «пока проверяемое значение — любое ненулевое число»
while 1:
pass
while -4:
pass
while 2023:
pass
Если сделать while 0, то цикл никогда не начнётся.
# Способ №3 — «пока проверяемое значение — непустой элемент»
while 'string':
pass
while [False, 'list', 0]:
pass
Если после while поставить пустой элемент — например, строку str() или список list(), то цикл никогда не начнётся.
# Способ №4 — корректное уравнение
while 1 == 1:
pass
while 0 != 1:
pass
Альтернативный подход — поместить после while переменную, в которой лежит подходящее условие. Например:
# Способ №1
condition = True
while condition:
pass
# Способ №2
condition = 1
while condition:
pass
# Способ №3
condition = 'string'
while condition:
pass
В таких случаях для выхода из цикла можно не использовать оператор break, а заменить значение в переменной condition на False, 0, None или любой пустой элемент. Цикл закончит последний виток и завершится, потому что условие больше не будет выполняться.
Такой подход применяется, когда нужно завершить цикл из других мест программы: например, из функции или вложенного цикла. Ещё одно отличие: так как цикл завершается «естественно», без оператора break, в нём выполнится else-код (если он есть).
condition = True
x = 0
while condition:
print(x)
x += 1
if x == 3:
condition = False
else:
print('Цикл завершился без break')
>>> 0
>>> 1
>>> 2
>>> Цикл завершился без break
Как сделать аналог do while в Python
В некоторых языках программирования есть ещё один вид цикла — с постусловием. Он всегда проходит хотя бы один виток и только после этого проверяет, выполняется ли условие. Вот его схема:

В Java и C++ такое достигается с помощью конструкции do while, но в Python её нет. Зато можно сделать аналог. Для этого нужно использовать бесконечный цикл, а внутри его тела прописать условие завершения.
x = 12
while True:
x += 1
print(x)
if x > 5:
break
>>> 13
Каким бы ни было значение x, такой цикл пройдёт хотя бы один виток. А это и есть постусловие.
Вложенные циклы в Python
Циклы в Python можно вкладывать друг в друга — то есть в теле одного цикла вызывать другой. Логика программы при этом усложняется.

Можно вкладывать друг в друга сколько угодно циклов. При этом для каждого нового уровня вложенности нужно увеличивать отступ. Выглядит это так:
while condition:
pass
while inner_condition:
pass
pass
Напишем программу, которая будет выводить номер итерации внешнего и внутреннего цикла.
for i in range(3):
print(f'Итерация внешнего цикла: {i}')
for j in range(2):
print(f'Итерация внутреннего цикла: {j}')
>>> Итерация внешнего цикла: 0
>>> Итерация внутреннего цикла: 0
>>> Итерация внутреннего цикла: 1
>>> Итерация внешнего цикла: 1
>>> Итерация внутреннего цикла: 0
>>> Итерация внутреннего цикла: 1
>>> Итерация внешнего цикла: 2
>>> Итерация внутреннего цикла: 0
>>> Итерация внутреннего цикла: 1
Резюмируем
- Циклы — один из основных инструментов любого Python-разработчика. С их помощью всего за пару строчек кода можно совершить сразу множество повторяющихся действий.
- Циклы состоят из условия и тела. Код в теле выполняется только до тех пор, пока соблюдено условие.
- В Python есть два вида циклов: while и for. В while условие задаётся явным образом. В for перебирается каждый элемент коллекции.
- К обоим видам можно применять разные операторы: break для прерывания, continue для пропуска части тела, else для совершения последнего действия перед выходом из цикла.
- Циклы можно делать бесконечными (тогда программа никогда не завершится или завершится только при выполнении определённого условия) и вкладывать друг в друга.
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!