Вложенные циклы for
Цикл внутри другого цикла — внешний и внутренний:
for i in range(3):
for j in range(2):
print(f"i={i}, j={j}")
# Вывод:
# i=0, j=0
# i=0, j=1
# i=1, j=0
# i=1, j=1
# i=2, j=0
# i=2, j=1
Таблица умножения
Классический пример вложенных циклов:
for i in range(1, 10):
for j in range(1, 10):
print(f"{i}*{j}={i*j:2}", end=" ")
print() # новая строка
break и continue во вложенных циклах
break/continue действуют только на ближайший цикл:
for i in range(3):
for j in range(3):
if j == 1:
break # прерывает только внутренний цикл
print(f"({i},{j})", end=" ")
print()
# Вывод:
# (0,0)
# (1,0)
# (2,0)
Внутренний цикл зависит от внешнего
Количество итераций внутреннего цикла может зависеть от переменной внешнего цикла:
for i in range(4):
for j in range(i): # внутренний цикл зависит от i
print("*", end="")
print() # новая строка
# Вывод:
#
# *
# **
# ***
При i = 0 внутренний цикл не выполняется ни разу (range(0) пуст), при i = 1 — один раз и так далее. Всего будет напечатано 0 + 1 + 2 + 3 = 6 звёздочек.
Сетка координат
Вложенные циклы удобны для генерации двумерных структур — например, сетки координат. Внешний цикл задаёт строку, внутренний — столбец:
for i in range(3):
for j in range(3):
print(f"({i},{j})", end=" ")
print()
# Вывод:
# (0,0) (0,1) (0,2)
# (1,0) (1,1) (1,2)
# (2,0) (2,1) (2,2)
Узор с диагональю
Выведем узор: единицы на главной диагонали (i == j), нули в остальных клетках:
for i in range(3):
for j in range(3):
if i == j:
print(1, end=" ")
else:
print(0, end=" ")
print()
# Вывод:
# 1 0 0
# 0 1 0
# 0 0 1
Как выйти сразу из всех вложенных циклов
break завершает только ближайший цикл. Чтобы выйти сразу из всех циклов, используют флаг — переменную-индикатор: ставим её в True во внутреннем цикле и проверяем в условии внешнего:
found = False
for i in range(5):
for j in range(5):
if i * j == 12:
print(f"Нашли: {i} × {j} = 12")
found = True
break # выходим из внутреннего цикла
if found:
break # выходим и из внешнего
# Вывод: Нашли: 3 × 4 = 12
Сложность вложенных циклов
Если внешний цикл выполняется N раз, а внутренний — M раз, то тело внутреннего цикла выполняется N × M раз. Такую зависимость обозначают O(N × M). Если N = M, то есть оба цикла по N итераций, используют обозначение O(N²):
for i in range(100): # N = 100
for j in range(100): # M = 100
pass # всего 100 × 100 = 10 000 итераций
Пирамидка из чисел
Соберём строку внутри цикла и выведем её. str(j) превращает число в строку, а strip() убирает лишний пробел в конце:
for i in range(1, 4):
row = ""
for j in range(1, i + 1):
row += str(j) + " "
print(row.strip())
# Вывод:
# 1
# 1 2
# 1 2 3