Волшебные циклы! Циклы for
Наконец-то настоящая автоматизация: вместо повторения кода вручную — просим Python повторить его самостоятельно.
Прежде чем Python: повторение вокруг нас
Мы повторяем действия постоянно, даже не задумываясь: чистим зубы одинаковыми движениями, маршируем одинаковыми шагами, поём куплет за куплетом одной и той же мелодии. Повторение — это отдельный, самостоятельный способ устроить действие, наравне с «сделать одно за другим» и «выбрать один из двух путей».
Три структуры алгоритма: вспоминаем
В главе 9 мы разобрали первые две из трёх фундаментальных структур, из которых складывается любой алгоритм. Третья — повторение — и есть тема этой главы.
if / elif / elsefor / whileЧто не так с этим кодом?
Вот квадрат из главы 6 — уже знакомый код: четыре одинаковых блока «шаг вперёд, поворот», записанных вручную:
artist.forward(100)
artist.right(90)
artist.forward(100)
artist.right(90)
artist.forward(100)
artist.right(90)
artist.forward(100)
artist.right(90)
А теперь представьте, что нужен не квадрат, а двадцатиугольник. Копировать эти две строки ещё 16 раз вручную — долго и легко ошибиться. Именно для таких повторяющихся блоков и существуют циклы: способ сказать Python «повтори это N раз» вместо того, чтобы копировать код руками.
Термины цикла
Прежде чем писать первый цикл, договоримся о словах, которыми будем его описывать — дальше они встретятся во всей главе:
| Термин | Что это |
|---|---|
| цикл | конструкция, которая повторяет один и тот же блок кода несколько раз |
| тело цикла | тот самый блок кода, который повторяется (строки с отступом под for/while) |
| итерация | один проход тела цикла — один «раз» из «повтори N раз» |
| условие | то, что цикл проверяет, чтобы решить, продолжать или остановиться |
| счётчик | переменная, которая считает номер итерации или меняется с каждым шагом |
Циклы for
Самый частый вид цикла в Python — for. Вместе с
range() он умеет повторить блок кода заданное число раз:
for i in range(5):
print(i)
Разбираем по словам
| Часть кода | Что означает |
|---|---|
for | «начинаем цикл» |
i | переменная цикла — на каждом шаге получает следующее значение из range(5) |
in range(5) | источник значений: числа от 0 до 4 |
: | дальше начинается тело цикла (с отступом) |
print(i) | тело цикла — то, что повторяется на каждой итерации |
Канонический flowchart цикла for
Важно сразу привыкнуть к правильной картине происходящего: for
не «выполняет тело N раз по волшебству» — на каждом шаге он спрашивает «есть ли следующий
элемент?», и если да — выполняет тело и спрашивает снова:
Трасса выполнения
Таблица трассировки — способ построчно проследить, что происходит на каждой итерации. Мы будем пользоваться такой таблицей всю главу:
| Итерация | i | Вывод (print) |
|---|---|---|
| 1 | 0 | 0 |
| 2 | 1 | 1 |
| 3 | 2 | 2 |
| 4 | 3 | 3 |
| 5 | 4 | 4 |
range(5) — от 0 до 4. range(2, 8) — от 2 до 7. range(0, 10, 2) — от 0 до 8 с шагом 2: 0, 2, 4, 6, 8. Подробный разбор — на следующей странице.Когда переменная цикла не нужна
Если само число повторов важно, а не значение счётчика — по традиции его называют
_ (нижнее подчёркивание), сигнализируя «это значение
сознательно не используется»:
artist.forward(100)
artist.right(90)
artist.forward(100)
artist.right(90)
artist.forward(100)
artist.right(90)
artist.forward(100)
artist.right(90)
for _ in range(4):
artist.forward(100)
artist.right(90)
for. Он не «современнее» в смысле версии Python — циклы существуют с самых первых версий языка, — но именно ради него стоило дочитать до этой главы: то же самое поведение, в 4 раза короче, и легко изменить число повторов одной цифрой._ — обычное имя переменной, Python не обрабатывает его как-то по-особому. Это просто договорённость между программистами: «здесь мы намеренно не используем значение цикла». Написать for x in range(4): тоже сработает — но будет менее понятно читателю кода.