Чем while отличается от while True? Когда цикл становится бесконечным?
Видел два варианта и не пойму разницу: обычный while условие: и while True:. Запустил такое и программа зависла:
i = 0
while i < 5:
print(i) # печатает 0 бесконечно
Почему оно не останавливается? И зачем вообще писать while True, если это вроде бы вечный цикл?
2 ответа
while крутится, пока условие истинно, и проверяет его перед каждой итерацией. Твой цикл завис, потому что условие i < 5 НИКОГДА не становится ложным — внутри ты не меняешь i. Печатается 0, проверка снова 0 < 5 истинна, и так вечно. Это и есть классическая ошибка: условие, которое не двигается к выходу.
Исправление — менять переменную, от которой зависит условие:
i = 0
while i < 5:
print(i)
i += 1 # вот этой строки не хватало
# напечатает 0 1 2 3 4
Теперь про while True. Само по себе условие True всегда истинно, поэтому выход обеспечивает break внутри тела. Это нормальный и очень частый паттерн, когда условие выхода удобнее проверять в середине цикла, а не в начале:
while True:
answer = input("Введите 'q' для выхода: ")
if answer == 'q':
break # выходим из цикла
print("Вы ввели:", answer)
Почему так пишут, а не пихают условие в while: на момент первой проверки данных ещё нет (ввод происходит ВНУТРИ). С while answer != 'q' пришлось бы заводить answer до цикла и дублировать логику. while True + break читается честнее.
Итого:
while условие— выход, когда условие стало ложным. Следи, чтобы внутри что-то двигало его к ложности.while True— нарочно «бесконечный», но управляемыйbreak. Безbreak(илиreturn) он действительно вечный.
Ещё полезно знать continue (пропустить остаток итерации) и то, что break выходит только из своего цикла, а не из всех вложенных.
Добавлю про коварные «почти бесконечные» циклы, которые сложнее заметить, чем забытый i += 1.
x = 1.0
while x != 0.0: # опасно: float редко попадает ТОЧНО в 0.0
x -= 0.1
Из-за погрешности float x может проскочить мимо нуля и крутиться вечно. Правило: для чисел с плавающей точкой сравнивай не на равенство, а через >/< (например while x > 0). И то же с условиями, которые меняет внешний код/сеть — всегда продумывай, точно ли наступит выход. Если сомневаешься, добавь счётчик-предохранитель и break по лимиту итераций.