Что такое бесконечный цикл
Бесконечный цикл — это повторение, у которого нет выхода: проверка в заголовке while каждый раз даёт True. Python не считает это ошибкой и честно крутит цикл, пока его не остановят.
Здесь главное отличие от остальных страниц раздела. При NameError или IndexError Python печатает сообщение и останавливается сам. Ни в официальной документации Python, ни в списке встроенных исключений нет отдельной ошибки для зацикливания: распознать его должен сам программист. При зацикливании сообщения нет: программа либо бесконечно печатает одно и то же, либо молча «думает», и кажется, что компьютер завис. Запустите код в редакторе выше. Он должен отсчитать от 5 до 1 и вывести «Пуск!», но пятёрки будут сыпаться без конца, пока не сработает ограничение времени — защита редактора от зависания. После этого под выводом появится сообщение и подсказка.
otschet = 5
while otschet > 0:
print(otschet)
print("Пуск!")
Переменная otschet равна 5 и внутри цикла не меняется. Условие «5 больше 0» истинно сейчас, будет истинно через секунду и через час. Исправление — одна строка в теле цикла: otschet -= 1. Тогда на каждом шаге значение уменьшится, и после единицы условие станет ложным. В официальной документации Python оператор while описан именно так: тело повторяется, пока выражение в заголовке истинно. Как устроен сам оператор while, подробно рассказано в уроке про цикл while в Python.
otschet = 5
while otschet > 0:
print(otschet)
otschet -= 1
print("Пуск!")
Почему цикл не останавливается: 5 причин
Зацикливание почти всегда объясняется одной из 5 причин. Шаги цикла при этом выглядят одинаково, и все причины сводятся к вопросу: что внутри тела цикла меняет переменную из условия?
| Причина | Как выглядит | Как исправить |
| Счётчик не меняется | В теле нет i += 1 | Добавить изменение в конец тела |
| Счётчик идёт не туда | while i > 0: и i += 1 | Сменить знак шага или условие |
| Граница перепрыгнута | while x != 10: при шаге 2 от 1 | Использовать < вместо != |
| Изменение вне тела | i += 1 без отступа, после цикла | Сдвинуть строку внутрь блока |
| Нет выхода из while True | Нет break или условие для него не выполняется | Проверить ветку с break |
Первая строка таблицы — самый простой случай зацикливания: достаточно дописать одну команду. Четвёртая причина коварна тем, что строка с изменением есть, и глаз её видит. Но без отступа она стоит после цикла и выполнится, только когда цикл закончится, а он не закончится никогда. Это тот случай, когда отступ меняет смысл программы. Руководство PEP 8 требует 4 пробела на уровень[1]: ровный отступ помогает сразу увидеть, какие строки внутри тела.
Граница, которую цикл перепрыгнул
Условие с != опасно, если переменная меняется шагом больше 1: она может проскочить нужное значение и уйти дальше. Тогда цикл без конца ищет число, которого уже никогда не будет.
x = 1
while x != 10:
x += 2
print(x)
Шаги идут через один: переменная принимает значения 1, 3, 5, 7, 9, 11, 13… Десятки среди них нет: все числа нечётные. Условие «x не равно 10» остаётся истинным вечно. Такое зацикливание трудно заметить на глаз: код выглядит аккуратно. Исправление — сравнивать с запасом: while x < 10:. Тогда цикл остановится на первом значении, которое больше или равно 10, то есть на 11.
x = 1
while x < 10:
x += 2
print(x)
Этот приём полезно запомнить на будущее: в условии продолжения лучше писать <, >, <=, >=, а не !=, если только переменная не меняется ровно на 1. С дробными числами строгое равенство тем более не стоит использовать: из-за погрешности вычислений результат может отличаться от ожидаемого в последнем знаке.
Когда while True — это нормально
Запись while True — это намеренный бесконечный цикл с выходом через break внутри. Так пишут, когда заранее неизвестно, сколько будет повторений: ввод до стоп-слова, меню, игра.
В учебнике из официальной документации Python запись while True с break встречается в примере, где число запрашивают повторно, пока не введут правильно. По федеральной образовательной программе циклы с условием изучают в 8 классе, и тема зацикливания естественно возникает на тех же уроках.
summa = 0
while True:
slovo = input("Число или стоп: ")
if slovo == "стоп":
break
summa += int(slovo)
print("Сумма:", summa)
Такой цикл безопасен, только если до break действительно можно дойти. Документация Python описывает break как немедленный выход из ближайшего цикла: остальные шаги тела уже не выполняются. Типичная ошибка — проверка на «Стоп» с большой буквы, а пользователь вводит «стоп»; или input() стоит до цикла, и введённое слово больше не меняется. В Scratch такому циклу соответствует блок «повторять всегда»: игра должна работать, пока её не остановят красной кнопкой. В Python для игр и анимаций черепашкой тоже используют цикл без конца, но с понятным способом выхода. Ещё несколько примеров с break и continue собраны в материале с задачами на циклы.
«Бесконечный цикл — всегда ошибка программиста». Это миф: игры, меню и анимации намеренно работают без конца, а в Scratch для этого есть отдельный блок. Ошибка — только цикл без задуманного выхода.
«Цикл for не может быть бесконечным». Это не подтверждается: если в теле
for x in spisokдобавлять элементы в тот же список, перебор никогда не закончится. Цикл поrange()действительно конечен, но перебор изменяемого списка — нет.
Как остановить зависшую программу
Чтобы остановить программу, которая крутится без конца, нажмите Ctrl+C в окне, где она запущена. Python прервёт выполнение и напишет KeyboardInterrupt — это не ошибка кода, а след нажатия.
- Терминал или командная строка. Ctrl+C прерывает программу. Если она ждёт ввода, иногда нужно нажать ещё раз.
- IDLE. Ctrl+C в окне Shell или пункт меню Shell → Interrupt Execution. Если не помогло — Shell → Restart Shell.
- Редактор на нашем сайте. Делать ничего не нужно: ограничение времени работы само остановит выполнение и покажет подсказку.
- Scratch. Красный восьмиугольник «Стоп» рядом с зелёным флажком останавливает все скрипты.
Закрывать окно редактора кода с несохранённым файлом не стоит: остановка через Ctrl+C сохраняет и программу, и всё, что она успела вывести. По выводу как раз удобно искать причину. Установка Python и знакомство с IDLE описаны в статье про установку Python.
Как найти место зацикливания
Если программа длинная и непонятно, какой цикл виноват, помогут 3 приёма: отладочный вывод, предохранитель и ручная трассировка на бумаге.
Отладочный вывод в теле цикла
Добавьте в начало тела строку print() со значениями переменных из условия. Если шаги повторяют одно и то же значение снова и снова, вы нашли и цикл, и переменную, которая не меняется.
i = 0
while i < 3:
print("шаг", i, "условие", i < 3)
i += 1
Счётчик-предохранитель
На время отладки можно ограничить число повторений: завести переменную shagov, увеличивать её на каждом шаге и прерывать цикл после, например, 1000 повторов с сообщением. Так программа не будет крутиться вечно, а вы увидите, что граница достигнута. После исправления предохранитель лучше убрать, чтобы он не маскировал настоящую логику.
x = 1
shagov = 0
while x != 10:
x += 2
shagov += 1
if shagov > 1000:
print("Слишком много шагов, x =", x)
break
Третий приём — трассировочная таблица: столбцы для каждой переменной и условия, строки для шагов. Её рисуют на уроках информатики, и для поиска такой ошибки она особенно хороша: уже на 3–4 строке видно, что значение не приближается к границе. Больше способов искать ошибки описано в статье об отладке программ.
Когда совет «добавь break» не поможет
Добавить break наугад не поможет, если цикл крутится из-за неверной логики. В этих 4 случаях нужно менять условие или тело цикла.
- Break стоит во вложенном цикле. Он прерывает только 1 внутренний цикл, а внешний
whileпродолжает работать. - Условие для break зависит от ввода, который читается 1 раз до цикла. Перенесите
input()внутрь тела. - Сравнение строки с числом.
input()возвращает строку, и проверкаslovo == 0не выполнится ни на 1 шаге. Нужноint(slovo) == 0. - Цикл перебирает список, который растёт. Каждый шаг добавляет 1 новый элемент, и break до конца не доберётся — нужен второй список для результата.
Чего делать нельзя
Нельзя запускать программу снова и снова в надежде, что «в этот раз остановится»: без изменений в коде цикл поведёт себя точно так же.
- Нельзя писать
while Trueбез продуманного выхода черезbreakилиreturn. - Не следует сравнивать через
!=, если переменная меняется шагом больше единицы. - Не стоит менять переменную условия вне тела цикла — проверяйте отступ у строки с
+= 1. - Не допускается добавлять элементы в список, который перебирает этот же цикл.
- Не стоит оставлять в готовой программе отладочные print и предохранители.
- Нельзя проверять равенство дробных чисел в условии цикла: из-за округления оно может не выполниться никогда.
Если программа не крутится вечно, а падает с сообщением, разберите его по шагам из статьи как читать ошибки Python.
Источники
[1] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
[2] The Python Tutorial (официальная документация Python 3). Python Software Foundation. — синтаксис и встроенные функции.
[3] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования». — информатика 7–9 (см. факты).
Вопросы и ответы
Может ли бесконечный цикл сломать компьютер?
Нет. Он только занимает процессор, пока работает. После Ctrl+C или закрытия окна всё возвращается в норму. Осторожнее с циклами, которые копят данные в список: они могут занять много памяти.
Что значит KeyboardInterrupt?
Это сообщение о том, что программу прервали с клавиатуры, обычно сочетанием Ctrl+C. Исправлять тут нечего, но строка в сообщении покажет, где программа была в момент остановки.
Почему в редакторе сайта программа обрывается сама?
Там действует ограничение времени работы: если программа выполняется слишком долго, редактор её останавливает. Это защита вкладки браузера: без неё страница перестала бы отвечать.
Чем while отличается от for в смысле остановки?
for перебирает готовую последовательность, и по range() он всегда конечен. while работает, пока условие истинно, поэтому за его выходом нужно следить самому. Подробности — в официальной документации Python[2].
Изучают ли циклы с условием в школе?
Да, по федеральной образовательной программе циклы с условием и с переменной входят в курс информатики 8 класса[3]. Трассировочные таблицы там же помогают искать ошибки в циклах.
Есть ли в Scratch бесконечный цикл?
Да, это блок «повторять всегда». Для игр он нужен: персонаж должен реагировать на клавиши всё время, пока работает проект. Останавливают его кнопкой «Стоп».