Когда разбирали циклы, вы уже перебирали числа через range() и символы строки посимвольно. Но на практике у вас почти всегда есть готовая коллекция — список покупок, оценки за четверть, словарь с телефонами друзей — и нужно пройтись по ней всей, не считая, сколько в ней элементов, и не обращаясь к ним по номеру.
Хорошая новость: for умеет забирать элементы прямо из коллекции, без всяких индексов. Вы уже видели это на строке — сейчас разберём, как та же самая конструкция работает со списком, кортежем и словарём, и добавим удобную функцию enumerate(), которая пригодится, когда всё-таки нужен ещё и номер элемента.
for элемент in коллекция: — универсальная формула для перебора списков, кортежей и (с оговорками) словарей. Индексы для этого не нужны.Перебор списка
Простыми словами: представьте, что список — это стопка карточек на столе. Чтобы прочитать все карточки по очереди, вам не нужно считать их номера — вы просто берёте верхнюю, читаете, откладываете, берёте следующую. Именно так for работает со списком: на каждом шаге он сам достаёт очередной элемент и кладёт его в переменную цикла.
Официально коллекции, которые можно вот так перебрать по одному элементу, называются итерируемыми объектами (от англ. iterable). Список, кортеж, строка, словарь и множество — все они итерируемые. Синтаксис одинаковый для всех: for переменная in коллекция:.
grades = [5, 3, 4, 5, 2, 4]
total = 0
for grade in grades:
total += grade
average = total / len(grades)
print(f"Средняя оценка: {average:.1f}")
Разберём построчно:
grades = [5, 3, 4, 5, 2, 4]— список из шести оценок.total = 0— переменная-накопитель, в ней будем собирать сумму.for grade in grades:— на первом шагеgradeстановится равен5(первому элементу), на втором —3, и так далее, пока список не закончится. Индекс нигде не упоминается — Python сам знает, где остановиться.total += grade— на каждом шаге прибавляем текущую оценку к сумме.average = total / len(grades)— после цикла делим накопленную сумму на количество оценок, которое узнаём функциейlen().print(f"Средняя оценка: {average:.1f}")— выводим результат с одним знаком после запятой.
Средняя оценка: 3.8
Обратите внимание: раньше для перебора чисел от 0 до конца списка вам приходилось бы писать for i in range(len(grades)): и потом обращаться к элементу через grades[i]. Когда индекс сам по себе не нужен — такой код лишний. Перебор напрямую короче и меньше шансов ошибиться в границах.
Перебор кортежа
Простыми словами: кортеж — это тот же список, но запечатанный скотчем: содержимое можно посмотреть и перебрать, а вот поменять элементы местами или добавить новый уже нельзя. Для перебора это не имеет значения — читать содержимое кортежа можно точно так же, как список.
Официально это называется кортеж (англ. tuple) — неизменяемая упорядоченная коллекция. Записывается в круглых скобках через запятую. Подробно устройство кортежей разберём отдельно, а пока нам важно только одно: перебирается он абсолютно так же, как список.
colors = ("красный", "зелёный", "синий")
for color in colors:
print(f"Цвет: {color}")
colors = ("красный", "зелёный", "синий")— кортеж из трёх строк, скобки круглые вместо квадратных.for color in colors:— та же формула перебора: переменнаяcolorпо очереди получает каждый элемент кортежа.print(f"Цвет: {color}")— печатаем очередной элемент на каждом шаге.
Цвет: красный
Цвет: зелёный
Цвет: синий
enumerate: когда всё же нужен номер
Простыми словами: представьте очередь в кассу. Кассиру не важно, что именно вы несёте, ему важна только сама покупка — это обычный перебор. Но если вы ведёте список этой же очереди и хотите отметить «первый», «второй», «третий» — вам нужен ещё и порядковый номер каждого. Функция enumerate() как раз нумерует элементы коллекции на лету, прямо во время перебора.
Официально enumerate() — это готовая функция, которая оборачивает любую коллекцию и на каждом шаге отдаёт цикла for пару значений: индекс элемента и сам элемент. Чтобы получить их оба, слева от in пишут две переменные через запятую.
fruits = ["яблоко", "банан", "груша"]
for index, fruit in enumerate(fruits):
print(index, fruit)
fruits = [...]— обычный список из трёх строк.enumerate(fruits)— оборачивает список, на каждом шаге готовит пару «номер по порядку, элемент».for index, fruit in ...:— Python раскладывает подготовленную пару сразу в две переменные:indexполучает номер,fruit— сам элемент. Такое раскладывание пары по переменным называется распаковкой.print(index, fruit)— печатаем оба значения через пробел (это умолчание уprint()с несколькими аргументами).
0 яблоко
1 банан
2 груша
Заметили? Нумерация начинается с нуля — так же, как индексы. Если для вывода нужны привычные людям номера «с единицы», у enumerate() есть второй, необязательный аргумент — start:
for place, fruit in enumerate(fruits, start=1):
print(f"{place}. {fruit}")
# 1. яблоко
# 2. банан
# 3. груша
start=1 — именованный аргумент, он говорит функции, с какого числа начинать нумерацию. Сама коллекция от этого не меняется, меняются только числа, которые вы получаете в place.Перебор словаря
Простыми словами: представьте телефонную книгу — напротив каждого имени записан номер. Чтобы найти номер, вы ищете не по порядковому месту в книге, а по имени. Такая пара «имя — номер» в Python называется словарём: слева от каждой пары стоит подпись, справа — то, что за ней хранится.
Официально это словарь (англ. dict, от dictionary) — коллекция из пар ключ: значение. Записывается в фигурных скобках, пары разделяются запятой, а ключ и значение внутри пары — двоеточием: {ключ: значение, ключ: значение}. Подробно про словари поговорим отдельно, а пока разберёмся, как их перебирать циклом for.
student = {"имя": "Алия", "курс": 2, "город": "Алматы"}
for key in student:
print(key)
student = {...}— словарь из трёх пар:"имя"хранит"Алия","курс"хранит2,"город"хранит"Алматы".for key in student:— когда послеinстоит просто словарь без уточнения,forпо умолчанию перебирает только ключи, а не значения.
имя
курс
город
Ключей часто недостаточно — хочется получить сразу и значения. Для этого у словаря есть три готовых метода:
| Запись | Что получаем на каждом шаге |
|---|---|
for key in student |
только ключ |
for value in student.values() |
только значение |
for key, value in student.items() |
ключ и значение вместе |
scores = {"Алия": 5, "Борис": 3, "Вика": 4}
for name, score in scores.items():
print(f"{name}: {score}")
scores = {...}— словарь, где ключ — имя ученика, значение — его оценка..items()— метод словаря, который на каждом шаге отдаёт пару(ключ, значение).for name, score in scores.items():— так же, как сenumerate(), Python распаковывает пару сразу в две переменные:nameполучает ключ,score— значение.print(f"{name}: {score}")— печатаем имя и оценку через подстановку в f-строку.
Алия: 5
Борис: 3
Вика: 4
.items() — самый частый способ работы со словарём в цикле. Берите его по умолчанию, если в теле цикла нужны и ключ, и значение.Частые ошибки
Изменение списка прямо во время его перебора. Если вы удаляете или добавляете элементы в тот же список, по которому идёт for, Python не пересчитывает позиции заново на каждом шаге — часть элементов может быть пропущена.
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num) # опасно: меняем список во время перебора
print(numbers) # [1, 3, 5] совпало случайно, но 4 было пропущено
Перебор словаря и ожидание значений вместо ключей. Начинающие часто пишут for item in словарь: и удивляются, почему item — это имя, а не оценка.
scores = {"Алия": 5, "Борис": 3}
for item in scores:
print(item * 2) # TypeError: словарь отдаёт строки-ключи, не числа
.values() или .items() цикл по словарю всегда отдаёт только ключи. Если нужны значения — уточняйте это явно.Что важно запомнить
start)..values(), для пар «ключ, значение» — .items().Проверьте себя
5 вопросов
Сумма чётных чисел
Дан список чисел. Напишите программу, которая с помощью цикла for находит сумму всех чётных чисел этого списка.
numbers = [12, 7, 24, 9, 18, 5, 30, 11]Результат сохраните в переменную total и выведите в формате: Сумма чётных чисел: ...