Цикл в Python — конструкция, которая повторяет блок кода: for перебирает элементы коллекции, while повторяет тело, пока условие истинно. Отдельного цикла do while (с проверкой условия после тела) в Python нет. Его записывают как while True: с проверкой условия в конце тела и выходом через break — так тело гарантированно выполнится хотя бы один раз.
Содержание
- Короткий ответ: do while в Python
- Мини-словарь
- Цикл for: перебор элементов
- Цикл while: повтор по условию
- Сравнение: for, while и эмуляция do while
- break, continue и else у цикла
- Вложенные циклы и выход сразу из двух
- Частые ошибки: неверно -> результат -> исправление
- Выводы
- Где применяется / связь с практикой
- FAQ
Все примеры ниже проверены на Python 3.14.7, вывод взят из реального запуска.
Короткий ответ: do while в Python
В C, Java или JavaScript цикл do { ... } while (условие); сначала выполняет тело, потом проверяет условие. В Python то же поведение дает такой шаблон:
attempts = iter(["abc", "-5", "42"]) # имитация ввода пользователя
while True:
raw = next(attempts) # тело: выполняется минимум один раз
print("ввод:", raw)
if raw.isdecimal() and int(raw) > 0:
break # условие выхода проверяется ПОСЛЕ тела
print("принято:", int(raw))
Вывод:
ввод: abc
ввод: -5
ввод: 42
принято: 42
Типичный сценарий — повторять запрос ввода, пока пользователь не введет корректное значение. В реальной программе вместо next(attempts) будет input("Число: ").strip(). Обратите внимание на инверсию: в do while пишут условие продолжения, а здесь в if стоит условие выхода.
Проверка isdecimal() отсекает минус, пробелы и символы вроде ² (у "²".isdigit() результат True, но int("²") падает с ValueError). Но и после isdecimal() int() может упасть: строка из 5000 цифр проходит проверку, а int отклоняет ее с ValueError (лимит 4300 цифр при переводе строки в число, с Python 3.11). Поэтому для реального ввода, в том числе с отрицательными числами, надежнее try: int(raw) с except ValueError плюс проверка диапазона.
Мини-словарь
- Итерация — один проход тела цикла.
- Итерируемый объект — то, что можно перебрать в
for: список, строка, словарь,range, файл. - Предусловие — условие проверяется до тела (
while): тело может не выполниться ни разу. - Постусловие — условие проверяется после тела (do while): тело выполнится минимум один раз.
Цикл for: перебор элементов
for в Python — это цикл «для каждого элемента», а не счетчик, как for (i = 0; i < n; i++) в C. Он берет элементы итерируемого объекта по очереди, пока они не кончатся.
langs = ["Python", "Go", "Rust"]
for lang in langs:
print(lang, len(lang))
for i in range(1, 10, 3):
print(i, end=" ")
print()
for number, lang in enumerate(langs, start=1):
print(number, lang)
prices = {"кофе": 180, "чай": 120}
for name, price in prices.items():
print(f"{name}: {price} руб.")
Вывод:
Python 6
Go 2
Rust 4
1 4 7
1 Python
2 Go
3 Rust
кофе: 180 руб.
чай: 120 руб.
Разбор по частям:
range(start, stop, step)выдает целые числа отstartдоstopне включительно:range(1, 10, 3)дает 1, 4, 7. Один аргументrange(5)— это 0..4.enumerate()выдает пары «номер, элемент» — вместо ручного счетчика иrange(len(langs)).dict.items()перебирает пары «ключ, значение». Порядок — порядок вставки (гарантирован для словарей с Python 3.7).
Когда брать for: известна коллекция или число повторений.
Цикл while: повтор по условию
while проверяет условие перед каждой итерацией. Подходит, когда число повторов заранее неизвестно: например, сколько месяцев нужно, чтобы вклад 1000 при росте 10% в месяц превысил 1500.
balance = 1000
month = 0
while balance < 1500:
balance = balance * 1.1
month += 1
print(month, round(balance, 2))
Вывод: 5 1610.51. Условие проверено шесть раз, тело выполнено пять.
Внутри тела обязательно должно меняться что-то, от чего зависит условие. Иначе цикл станет бесконечным. Остановить зависшую программу в терминале можно сочетанием Ctrl+C — Python прервет ее с исключением KeyboardInterrupt.
Сравнение: for, while и эмуляция do while
| Конструкция | Когда проверяется условие | Минимум выполнений тела | Типичная задача |
|---|---|---|---|
for x in коллекция |
перед каждым элементом (есть ли следующий) | 0 (пустая коллекция) | обработать все элементы, повторить N раз |
while условие: |
до тела | 0 | повторять, пока верно условие |
while True: + if ...: break в конце |
после тела | 1 | запрос ввода, повтор операции до успеха |
while (x := f()): |
до тела, по результату f() |
0 | читать данные, пока они есть |
Последняя строка — оператор присваивания := (с Python 3.8). Это не do while: условие проверяется до тела, но функция вызывается в заголовке, и код не дублируется.
chunks = iter([b"abc", b"de", b""]) # имитация чтения файла кусками
while (chunk := next(chunks)):
print(len(chunk), chunk)
print("конец данных")
Вывод:
3 b'abc'
2 b'de'
конец данных
Иногда do while эмулируют флагом (done = False, while not done:) или дублированием тела перед while. Оба варианта рабочие, но дублирование опасно: исправив одну копию, легко забыть вторую. Шаблон while True + break короче и держит тело в одном месте.
break, continue и else у цикла
breakнемедленно завершает ближайший цикл.continueпропускает остаток тела и переходит к следующей итерации.elseпосле цикла выполняется, если цикл закончился сам, безbreak.
n = 0
while True:
n += 1
if n % 2 == 0:
continue # четные пропускаем, print ниже не выполнится
if n > 7:
break # выход из цикла
print(n, end=" ")
print("| вышли при n =", n)
Вывод: 1 3 5 7 | вышли при n = 9. При n = 8 сработал continue, до break дело дошло на n = 9.
Блок else удобен в поиске: он отвечает на вопрос «перебрали все и не нашли».
import math
def find_divisor(n):
for d in range(2, math.isqrt(n) + 1):
if n % d == 0:
print(n, "делится на", d)
break
else:
print(n, "- простое число")
find_divisor(91)
find_divisor(97)
Вывод:
91 делится на 7
97 - простое число
Граница: else выполнится и тогда, когда цикл не сделал ни одной итерации (пустой список, ложное с самого начала условие while). Функция выше рассчитана на целые n >= 2: для 0 и 1 цикл пустой, и else ошибочно назовет их простыми. Для них нужна отдельная проверка до цикла. Корень считаем через math.isqrt (целочисленный, с Python 3.8), а не int(n ** 0.5): для очень больших n дробный корень теряет точность, а при n больше примерно 10^308 падает с OverflowError: int too large to convert to float.
Вложенные циклы и выход сразу из двух
break прерывает только внутренний цикл. Чтобы выйти из обоих, вынесите их в функцию и используйте return:
grid = [
[1, 3, 5],
[7, 8, 9],
[10, 12, 13],
]
odd_only = [
[1, 3],
[5, 7],
]
def first_even(matrix):
for i, row in enumerate(matrix):
for j, value in enumerate(row):
if value % 2 == 0:
return i, j, value # return выходит сразу из обоих циклов
return None
print(first_even(grid))
print(first_even(odd_only))
Вывод: (1, 1, 8) и None. Если вложенность нужна для перебора всех комбинаций, ее можно заменить одним циклом по itertools.product(["S", "M"], ["red", "blue"]) — он выдаст пары S red, S blue, M red, M blue.
Частые ошибки: неверно -> результат -> исправление
1. Удаление элементов списка во время перебора.
nums = [1, 2, 2, 3, 4]
for x in nums:
if x % 2 == 0:
nums.remove(x)
print(nums)
Результат: [1, 2, 3] — одна двойка осталась. После удаления элементы сдвигаются, и цикл перескакивает через следующий. Исправление — собрать новый список:
nums = [1, 2, 2, 3, 4]
nums = [x for x in nums if x % 2 != 0]
print(nums)
Результат: [1, 3].
2. Условие while, которое никогда не станет ложным. Цикл while x != 0: x -= 3 при x = 10 не остановится: значения 10, 7, 4, 1, -2 проскакивают ноль. Со страховкой на 100 шагов прогон печатает стоп: x = -293. Исправление — условие-неравенство while x > 0:, после цикла x равен -2.
3. Дробный шаг в range.
for x in range(0, 1, 0.25):
print(x)
Результат:
TypeError: 'float' object cannot be interpreted as an integer
range работает только с целыми. Исправление — перебирать целый счетчик и делить:
for i in range(4):
x = i / 4
print(x, end=" ")
print()
Результат: 0.0 0.25 0.5 0.75.
Выводы
forперебирает элементы итерируемого объекта,whileповторяет тело, пока условие истинно.- Цикла do while в Python нет; его заменяет
while True:сif условие_выхода: breakв конце тела. breakвыходит из ближайшего цикла,continueпропускает итерацию,elseу цикла срабатывает, если не былоbreak(в том числе при нуле итераций).- Из вложенных циклов удобнее всего выходить через
returnиз функции. - Не меняйте список, который перебираете, и следите, чтобы условие
whileмогло стать ложным.
Где применяется / связь с практикой
Освойте тему на практике
Циклы стоят за любой обработкой данных: разбор файлов и логов, повтор сетевого запроса до успеха, обход строк таблицы, валидация пользовательского ввода. На курсе «Python-разработчик. Базовый уровень» циклы, функции и коллекции отрабатываются на практических задачах с ревью кода. Разобраться с темой в живом формате можно на открытых уроках Otus.
FAQ
Почему в Python нет do while?
Предложение расширить while блоком do:, который выполняется до проверки условия (PEP 315), было отклонено: по итогу обсуждения ни один синтаксис не оказался лучше шаблона while True с if not условие: break.
Что быстрее — for или while?
Для перебора коллекции for обычно быстрее и короче: ему не нужен ручной счетчик и проверка условия на каждом шаге. Для точной оценки на своих данных используйте модуль timeit.
Можно ли изменить переменную цикла for внутри тела?
Можно, но на следующей итерации она получит очередное значение из range или коллекции. Чтобы управлять шагом вручную, используйте while.



