Python для новичковУправление ходом программыЦикл for и функция range

Цикл for и функция range

Уроки курсаЦикл for и функция range

Вложенные циклы for: таблица умножения

До сих пор в теле цикла были простые выражения — print, арифметика. Но тело цикла — это обычный блок кода, и внутри него можно написать ещё один цикл. Такая конструкция называется вложенными циклами.

Вот как это работает: внешний цикл делает одну итерацию, и пока он «стоит» на ней, внутренний цикл прокручивается полностью от начала до конца. Потом внешний переходит к следующей итерации — и внутренний снова запускается с нуля.

Классический пример — таблица умножения:

for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i} × {j} = {i * j}")

Внешний цикл перебирает i от 1 до 9. На каждом значении i внутренний цикл прогоняет j от 1 до 9 и печатает строку вида 1 × 1 = 1, 1 × 2 = 2, ..., 1 × 9 = 9. Затем i становится 2, внутренний цикл запускается снова: 2 × 1 = 2, 2 × 2 = 4, ... Итого программа выведет 81 строку — по 9 строк на каждое из 9 значений i.

Обратите внимание на отступы: тело внутреннего цикла сдвинуто на два уровня — восемь пробелов. Python определяет вложенность именно по отступу, и если случайно сдвинуть print на один уровень меньше, он окажется в теле внешнего цикла, а не внутреннего.

# Ошибка в отступе
for i in range(1, 10):
    for j in range(1, 10):
        pass  # внутренний цикл ничего не делает
    print(f"{i} × {j} = {i * j}")  # выполняется только после внутреннего цикла

Здесь print находится на уровне внутреннего цикла, а не внутри него. В результате для каждого i напечатается только одна строка — та, где j уже равно 9 (последнее значение после завершения внутреннего цикла). Таблица умножения не получится.

Если нужно разделить строки по множителям и получить более читаемый вывод, можно добавить пустую строку после каждой строки таблицы:

for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i} × {j} = {i * j}")
    print()  # пустая строка после каждой группы — это уже внешний цикл

Здесь print() без аргументов стоит на уровне внешнего цикла: он выполняется один раз после того, как внутренний цикл отработал все девять итераций для текущего i. Именно расположение этой строки — на один отступ левее — меняет поведение программы.

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