Цикл while в питоне
Цикл while («пока») позволяет выполнить
одну и ту же последовательность действий, пока проверяемое условие истинно.
Условие записывается до тела цикла и проверяется до выполнения тела цикла.
Как правило, цикл while используется, когда невозможно
определить точное значение количества проходов исполнения цикла.
Синтаксис цикла while в простейшем случае выглядит так:
while условие:
блок инструкций
При выполнении цикла while сначала проверяется условие.
Если оно ложно, то выполнение цикла прекращается и управление
передается на следующую инструкцию после тела цикла while.
Если условие истинно, то выполняется инструкция, после чего условие
проверяется снова и снова выполняется инструкция.
Так продолжается до тех пор, пока условие будет истинно.
Как только условие станет ложно, работа цикла завершится и
управление передастся следующей инструкции после цикла.
Например, следующий фрагмент программы напечатает на экран
все целые числа от 1 до 10. Видно, что цикл
while может заменять цикл for ... in range(...):
i = 1
while i <= 10:
print(i)
i += 1
В этом примере переменная i внутри цикла изменяется от 1 до 10.
Такая переменная, значение которой меняется с каждым новым проходом цикла,
называется счетчиком. Заметим, что после выполнения этого фрагмента
значение переменной i будет равно 11,
поскольку именно при i==11 условие i<=10 впервые
перестанет выполняться.
Вот еще один пример использования цикла while
для определения количества цифр натурального числа n:
n = int(input())
length = 0
while n > 0:
n //= 10
length += 1
В этом цикле мы отбрасываем по одной цифре числа, начиная с конца,
что эквивалентно целочисленному делению на 10 (n //= 10),
при этом считаем в переменной length, сколько раз это было сделано.
В языке Питон есть и другой способ решения этой задачи, если исходное число n ещё не изменено циклом:
length = len(str(n)).
Инструкции управления циклом
После тела цикла можно написать слово else:
и после него блок операций, который будет
выполнен один раз после окончания цикла, когда проверяемое
условие станет неверно:
i = 1
while i <= 10:
print(i)
i += 1
else:
print('Цикл окончен, i =', i)
Казалось бы, никакого смысла в этом нет, ведь эту же инструкцию можно
просто написать после окончания цикла. Смысл появляется только
вместе с инструкцией break, использование которой внутри цикла
приводит к немедленному прекращению цикла, и при этом не исполняется ветка
else. Обычно инструкцию break используют внутри if,
чтобы завершить цикл при выполнении особого условия.
Другая инструкция управления циклом —
continue (продолжение цикла). Если эта инструкция
встречается где-то посередине цикла, то пропускаются все оставшиеся
инструкции до конца цикла, и исполнение цикла продолжается
со следующей итерации. В цикле while это означает повторную
проверку условия. Если перед continue не обновить переменные,
от которых зависит условие, цикл может стать бесконечным.
Инструкции break, continue и ветка
else: можно использовать и внутри цикла for.
Тем не менее, увлечение инструкциями break и continue
не поощряется, если можно обойтись без их использования. Вот типичный пример
плохого использования инструкции break.
while True:
length += 1
n //= 10
if n == 0:
break
Обработка последовательности в while
Иногда нужно обрабатывать последовательность объектов до тех пор, пока не встретится какой-то «особый» объект.
И тут есть два варианта: нужно остановиться после обработки «особого» объекта, либо до.
Ниже приведены условные схемы, а не готовые программы: слова
взять_следующий и обработать обозначают действия.
Проверка is not подходит для специального объекта-маркера
(например, None); при сравнении чисел или строк по значению
следует использовать !=.
Если «особый» элемент нужно обработать, то обычно пишут так:
x = любое_не_особое_значение
while x is not особый:
x = взять_следующий
обработать
Если «особый» элемент НЕ нужно обрабатывать (то есть нужно остановиться сразу), то обычно пишут так:
x = взять_следующий
while x is not особый:
обработать
x = взять_следующий
Первый вариант использования цикла предпочтителен сразу по нескольким причинам.
Во-первых, каждая итерация цикла начинается с взятия нового значения.
Если мы на предыдущей итерации сделали continue, то в этой итерации сразу всё ок.
Во-вторых, значение заполняется ровно в одном месте.
Если код для получения нового значения длинный, то он не будет дублироваться.
Ну и без дублирования кода нельзя забыть исправить дубль.
Начиная с Python 3.8 можно записать и второй вариант обработки без повторов
с помощью выражения присваивания :=, вот так:
while (x := взять_следующий) is not особый:
обработать