Вложенные циклы
Вложенные циклы
Цикл может находиться внутри другого цикла — это называется вложенные циклы. Для каждой итерации внешнего цикла внутренний цикл выполняется полностью от начала до конца. Это мощный инструмент для работы с двумерными структурами данных и комбинаторными задачами.
Синтаксис и принцип работы
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
Производительность и читаемость
Вложенные циклы — мощный инструмент, но используйте их осторожно:
- Три и более уровней вложенности трудно читать — постарайтесь избежать.
- Квадратичная сложность O(n²) быстро растёт: на n=1000 это миллион итераций.
- Если данные структурированы (словари, множества), часто есть алгоритм лучше, чем перебор всех пар.
Проверь себя
Сколько раз выведется "*" в следующем коде?
for i in range(4):
for j in range(i + 1):
print("*", end="")
print()
i=0 → j от 0 до 0 → 1 звёздочка.
i=1 → j от 0 до 1 → 2 звёздочки.
i=2 → j от 0 до 2 → 3 звёздочки.
i=3 → j от 0 до 3 → 4 звёздочки.
Итого: 1 + 2 + 3 + 4 = 10.
Итог
- Вложенные циклы — цикл внутри цикла; для каждой итерации внешнего внутренний проходит полностью.
- Общее число итераций равно произведению длин всех уровней.
breakвыходит только из ближайшего (внутреннего) цикла.- Для выхода из нескольких уровней — флаговая переменная.
- Типичные применения: таблицы, паттерны, поиск пар, матричные операции.
- Избегайте трёх и более уровней вложенности — ищите более эффективный алгоритм.
Модуль 4 завершён! Вы освоили оба типа циклов Python, range(), управляющие операторы и вложенность. В следующем модуле переходим к коллекциям — начнём со списков и кортежей.