Перейти к содержанию

412 уроков, 25 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 5 из 20 Начальный 15 мин 100 XP

Цикл while в Python: повторять, пока условие

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

Редакция Питоники

Циклы for из первых уроков знают, по чему идут: список, диапазон, строка — число шагов известно заранее. Но половина повторов в жизни так не устроена: месить тесто, пока оно не станет однородным; ждать автобус, пока не придёт; снимать копейки, пока копилка не наберётся. Сколько шагов потребуется — сказать заранее нельзя, зато можно назвать условие окончания. Для таких повторов в Python есть второй вид цикла — while: «пока верно условие — делай».

while: пока условие верно

Обратный отсчёт: пока счётчик больше нуля — печатаем и уменьшаем:

первый while
count = 3
while count > 0:
    print(f'Осталось: {count}')
    count = count - 1
print('Время вышло!')
Вывод
Осталось: 3
Осталось: 2
Осталось: 1
Время вышло!

Механизм такой: Python проверяет условие count > 0. Верно — выполняет тело и возвращается к проверке. Верно снова — тело снова. На четвёртой проверке count равен 0, условие становится ложным, и цикл закончен — программа идёт дальше, к строке без отступа. while повторяет тело, пока условие верно, и заново проверяет его перед каждым шагом. Каждая итерация — одна и та же проверка, повторённая снова и снова.

Переменная внутри обязана меняться

Тело цикла отвечает не только за работу, но и за приближение к концу: переменная из условия должна двигаться. Удвоение — пример, где условие справедливо до самого предела:

удвоение до порога
number = 1
while number <= 50:
    print(number)
    number = number * 2
Вывод
1
2
4
8
16
32

number растёт: 1, 2, 4, 8, 16, 32 — а 64 уже больше 50, условие ложь, цикл стоп. Каждая итерация двигала переменную к выходу — в этом гарантия окончания. Если же тело ничего не меняет, условие проверяет одно и то же значение и остаётся истинным всегда. Так рождается бесконечный цикл:

цикл без выхода
# count внутри не меняется: условие всегда истинно
count = 3
while count > 0:
    print(count)
Не запускаем: тело печатает 3 бесконечно, вкладка зависнет. В терминале такой цикл останавливают Ctrl+C. Чинится добавлением строки count = count - 1 в тело.

Три способа записать шаг к выходу

Строку, которая двигает переменную условия, пишут тремя способами, и все три встречаются в живом коде одинаково часто. Разница чисто косметическая, но путаница между ними стоит времени: если в теле цикла смешаются две записи, работать будет одна, а читать придётся обе.

короткая запись шага
count = 3
while count > 0:
    print(count)
    count -= 1
Вывод
3
2
1

count -= 1 — это короткая запись count = count - 1. Так же работают +=, *=, /=: оператор приписывается к знаку равно. Если в теле цикла есть и полная запись, и короткая, отладка становится мучением: придётся искать, где именно счётчик поехал не туда. Выберите один стиль на проект и держитесь его.

Второй способ — менять величину по правилу задачи, а не на единицу:

шаг делением
n = 10
while n > 0:
    n = n // 2
    print('осталось', n)
Вывод
осталось 5
осталось 2
осталось 1
осталось 0

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

while ждёт событие

Сильная сторона while — ожидание: повторяем попытки, пока не случится нужное событие. Подберём пароль, перебирая список попыток, — сколько шагов уйдёт, заранее не знает никто:

пока не угадали
password = ''
attempts = ['123', 'qwerty', 'parrot']
i = 0
while password != 'parrot':
    password = attempts[i]
    i = i + 1
    print(f'пробуем: {password}')
print('вошли!')
Вывод
пробуем: 123
пробуем: qwerty
пробуем: parrot
вошли!

Условие password != 'parrot' звучит как человеческое: «пока пароль не угадан — пробуем следующий». Цикл сам остановился на третьей попытке, а мог бы на первой или пятой — число шагов определяется событием, не списком. Ещё одно типичное ожидание — пока список не опустеет. Метод pop() вынимает последний элемент, список тает с каждым шагом:

пока список не опустеет
boxes = ['кубик', 'мяч']
while len(boxes) > 0:
    box = boxes.pop()
    print(f'достали {box}')
print('коробка пуста')
Вывод
достали мяч
достали кубик
коробка пуста

Ограничитель попыток

Самый полезный вид while в реальном коде — цикл с предохранителем. Он ждёт события, но не бесконечно: если событие не наступило за N попыток, цикл выходит по другому условию. Так устроены вход в систему, повтор запроса к серверу, ожидание ответа.

попытки с ограничением
attempts = 0
limit = 3
while attempts < limit:
    attempts = attempts + 1
    print(f'попытка {attempts} из {limit}')
print('попытки кончились')
Вывод
попытка 1 из 3
попытка 2 из 3
попытка 3 из 3
попытки кончились

Условие здесь составное, но логика простая: пока попыток меньше лимита — пробуем. Строка после цикла выполняется всегда, независимо от исхода, и в ней разумно написать, что делать, когда попытки исчерпаны: сообщить об ошибке, вызвать другую ветку кода.

Граница условия: один шаг решает

Знак сравнения в условии — это граница перебора. Замените > на >=, и отсчёт получит лишний шаг — ноль:

отсчёт, дотянувшийся до нуля
count = 3
while count >= 0:
    print(f'{count}...')
    count = count - 1
print('Пуск!')
Вывод
3...
2...
1...
0...
Пуск!

С count > 0 цикл из первого блока останавливался на единице; с >= 0 — доходит до нуля. Ни один из вариантов не ошибка: граница выбирается задачей. Но проверяйте её на маленьком примере — сдвиг на шаг здесь случается чаще, чем где-либо. Ещё одна граница — синтаксическая: в условии цикла сравнение пишется двойным знаком равенства, как во всяком if:

= вместо == в условии
# = присваивает значение, == сравнивает
count = 3
while count = 0:
    print('готово')
Не запускается: SyntaxError. Один знак = это присваивание, Python запрещает присваивание внутри условия. Сравнение пишется двойным ==.

Два условия: and и or

В условии while может быть не одна проверка, а несколько, соединённых словами and и or. Здесь важно помнить, что условие должно быть вычислимым: Python требует, чтобы выражение можно было оценить как истину или ложь.

два ограничения сразу
bread = 3
jam = 5
sandwiches = 0
while bread > 0 and jam > 0:
    bread = bread - 1
    jam = jam - 1
    sandwiches = sandwiches + 1
print('бутербродов:', sandwiches)
Вывод
бутербродов: 3

Цикл крутится, пока есть и хлеб, и джем. Как только закончился хотя бы один, условие стало ложным — и вышел цикл. Три бутерброда при трёх хлебах и пяти банках джема: ограничило то, что кончилось первым.

Со словом or выходит наоборот — цикл живёт, пока верно хотя бы одно из условий. Такая конструкция удобна там, где есть несколько независимых причин выхода, и удобнее их перечислить, чем писать вложенные if.

while для суммы: тот же результат, что у for

Сумма первых ста чисел считается и через for с range, и через while — результат одинаковый, тело разное. Разница в том, кто отвечает за счётчик: в for его даёт range, в while вы обязаны написать шаг сами.

сумма через while
total = 0
n = 1
while n <= 100:
    total = total + n
    n = n + 1
print(total)
Вывод
5050

Пять тысяч пятьдесят — сумма от одного до ста. Этот пример хорош как проверка: если число сходится к такому же, как в математической формуле, значит цикл посчитал всё до конца и ни разу не вышел за границу. На нём же ловится забытый n = n + 1: без него цикл не закончится никогда, а с ним — пройдёт ровно сто шагов.

while и for: когда какой

Любой отсчёт while умеет повторить и for с range — сравните:

те же квадраты, что дал бы range(1, 6)
n = 1
while n <= 5:
    print(n * n)
    n = n + 1
Вывод
1
4
9
16
25
Цикл forЦикл while
Число шагов известно: длина списка или rangeЧисло шагов неизвестно: решает условие
Ходит по данным: список, строка, словарь, файлЖдёт событие: совпадение, предел, пустой список
Переменная цикла получает элементы самаПеременную условия создаёте и меняете вы
Зависание невозможно: шагов ровно столько, сколько данныхБез шага к выходу — бесконечный цикл
  • перебор данных — for: корзина, строки файла, диапазон номеров — урок про range;
  • ожидание события — while: верный пароль, набранная сумма, опустевший список;
  • выход по событию внутри перебора — это уже break: следующий урок про досрочный выход;
  • прототип бесконечного цикла с осмысленным выходом — while True с break, он разбирается позже в разделе.

while доверяет вашей дисциплине: гарантия выхода — не конструкция языка, а ваша строка внутри тела. Иногда удобнее перевернуть правило: перебирать без ограничений, а выходить по событию. Для досрочного выхода у Python есть оператор break — им и займёмся дальше.

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

n = 2
while n > 0:
    print(n)
    n = n - 1
x = 1
while x < 10:
    x = x * 3
print(x)
n = 5
while n > 2:
    print(n)
    n = n - 2
Проверь себя
0 / 9

1. Когда Python проверяет условие в while?

2. Из-за чего цикл while становится бесконечным?

3. Что произойдёт, если условие while ложно сразу, с первого раза?

4. Для какой задачи выбирают while, а не for?

5. Что не так с записью while count = 0?

6. Чем while count >= 0 отличается от while count > 0 при одинаковом теле?

7. Что делает условие while bread > 0 and jam > 0?

8. Чем count -= 1 отличается от count = count - 1?

9. Зачем в цикле ожидания ставят счётчик попыток?

Карточки терминов
Запомнено: 0 / 9
Практика

Копилка: money начинается с 0. Пока в копилке меньше 100, кладите по 30 и печатайте накопленную сумму после каждого взноса. Напечатайте суммы, которые увидит печать.

practice.py
Вопросы и ответы по уроку

Чем цикл while отличается от for в Python?

for ходит по данным: список, строка, range — число шагов известно. while повторяет тело, пока условие верно: число шагов заранее неизвестно, конец определяет условие. Правило: перебор данных — for, ожидание события — while.

Урок 2: range — цикл со счётчиком

Как работает while в Python простыми словами?

Проверь условие: если верно — выполни тело и вернись к проверке; если нет — продолжай программу после цикла. Счётчик для while создаёте вы сами и уменьшаете внутри тела: count = 3; while count > 0: print(count); count = count - 1.

Почему цикл while зависает и что делать?

Зависание — это бесконечный цикл: переменная условия не меняется в теле, и условие всегда истинно. Лечение — строка, двигающая переменную к выходу (count = count - 1). В терминале зависший цикл останавливают Ctrl+C, в песочнице — перезагрузкой вкладки, поэтому в уроках такие примеры не запускаются.

Что делает while True?

while True — намеренно бесконечный цикл: условие всегда истинно. Выходят из него оператором break по событию — так строят меню и игровые циклы. Это отдельная тема раздела; небрежное while True без break — верное зависание.

Урок 6: break — выход из цикла

Как посчитать сумму чисел от 1 до 100 через while?

Счётчик и аккумулятор: total = 0, n = 1, затем while n <= 100: total = total + n; n = n + 1. Ответ — 5050. Забытый шаг n = n + 1 сделает цикл бесконечным.

Можно ли в условии while использовать and и or?

Да, условие может быть составным. С and цикл живёт, пока верны все проверки; с or — пока верна хотя бы одна. Для цикла ожидания это удобный способ задать сразу два ограничения.

Понравился урок? Сошлитесь на него

«while повторяет тело, пока условие верно, и заново проверяет его перед каждым шагом.»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Что дальше

Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.