Вложенные циклы

Вложенные циклы

Цикл может находиться внутри другого цикла — это называется вложенные циклы. Для каждой итерации внешнего цикла внутренний цикл выполняется полностью от начала до конца. Это мощный инструмент для работы с двумерными структурами данных и комбинаторными задачами.

Синтаксис и принцип работы

for i in range(внешний_диапазон):
    for j in range(внутренний_диапазон):
        # тело — выполняется для каждой пары (i, j)

Простой пример: вывести все пары чисел:

for i in range(1, 4):   # i = 1, 2, 3
    for j in range(1, 4):   # j = 1, 2, 3
        print(f"({i}, {j})", end="  ")
    print()   # перевод строки после каждой строки таблицы

Вывод:

(1, 1)  (1, 2)  (1, 3)
(2, 1)  (2, 2)  (2, 3)
(3, 1)  (3, 2)  (3, 3)

Для i = 1 внутренний цикл пробегает j = 1, 2, 3. Затем i = 2 — и снова j = 1, 2, 3. Итого 3 × 3 = 9 итераций.

Подсчёт итераций

Общее количество итераций вложенных циклов — произведение количеств итераций каждого уровня. Это важно для оценки производительности:

for i in range(100):
    for j in range(100):
        pass   # 100 × 100 = 10 000 итераций

for i in range(100):
    for j in range(100):
        for k in range(100):
            pass   # 100^3 = 1 000 000 итераций!

Таблица умножения

Классический пример вложенных циклов:

for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i * j:3d}", end="")   # :3d — выравнивание по 3 символа
    print()

Вывод (первые строки):

  1  2  3  4  5  6  7  8  9
  2  4  6  8 10 12 14 16 18
  3  6  9 12 15 18 21 24 27

Паттерны из символов

Вложенные циклы часто используются для рисования паттернов:

# Прямоугольник 5 × 3
rows, cols = 3, 5
for i in range(rows):
    for j in range(cols):
        print("*", end="")
    print()
*****
*****
*****
# Треугольник
n = 5
for i in range(1, n + 1):
    print("*" * i)
*
**
***
****
*****

Поиск в двумерных структурах

Вложенные циклы — естественный способ перебирать пары элементов:

# Найти все пары из списка, сумма которых равна target
numbers = [1, 5, 3, 7, 2, 4]
target = 8

for i in range(len(numbers)):
    for j in range(i + 1, len(numbers)):   # j > i, чтобы не повторять пары
        if numbers[i] + numbers[j] == target:
            print(f"{numbers[i]} + {numbers[j]} = {target}")

Вывод: 1 + 7 = 8, 5 + 3 = 8, 4 + 4 = 8 (если бы 4 встречалась дважды). Начало внутреннего цикла с i + 1 исключает дублирование: не будем проверять одну и ту же пару дважды.

break и continue во вложенных циклах

break выходит только из непосредственно охватывающего цикла:

for i in range(3):
    for j in range(3):
        if j == 1:
            break   # выход из внутреннего цикла
        print(f"i={i}, j={j}")
    # сюда попадаем после break из внутреннего — внешний продолжается
    print(f"После внутреннего, i={i}")

Чтобы выйти из нескольких уровней вложенности сразу, используют флаг:

found = False
for i in range(5):
    for j in range(5):
        if i * j == 6:
            found = True
            break
    if found:
        break

print(f"Нашли: i={i}, j={j}")   # i=2, j=3

Производительность и читаемость

Вложенные циклы — мощный инструмент, но используйте их осторожно:

  1. Три и более уровней вложенности трудно читать — постарайтесь избежать.
  2. Квадратичная сложность O(n²) быстро растёт: на n=1000 это миллион итераций.
  3. Если данные структурированы (словари, множества), часто есть алгоритм лучше, чем перебор всех пар.

Проверь себя

Сколько раз выведется "*" в следующем коде?

for i in range(4):
    for j in range(i + 1):
        print("*", end="")
    print()

i=0j от 0 до 0 → 1 звёздочка.
i=1j от 0 до 1 → 2 звёздочки.
i=2j от 0 до 2 → 3 звёздочки.
i=3j от 0 до 3 → 4 звёздочки.
Итого: 1 + 2 + 3 + 4 = 10.

Итог

  • Вложенные циклы — цикл внутри цикла; для каждой итерации внешнего внутренний проходит полностью.
  • Общее число итераций равно произведению длин всех уровней.
  • break выходит только из ближайшего (внутреннего) цикла.
  • Для выхода из нескольких уровней — флаговая переменная.
  • Типичные применения: таблицы, паттерны, поиск пар, матричные операции.
  • Избегайте трёх и более уровней вложенности — ищите более эффективный алгоритм.

Модуль 4 завершён! Вы освоили оба типа циклов Python, range(), управляющие операторы и вложенность. В следующем модуле переходим к коллекциям — начнём со списков и кортежей.

Попробуйте интерактивную версию

Практические задачи, квизы и AI-наставник — бесплатный старт без карты

Перейти к практике