$ sudo teach IT
Модуль 5 · Коллекции · Урок 5.4

for по коллекциям

Один и тот же for перебирает список, кортеж и словарь напрямую — без счётчиков и обращений по индексу.

Теория + практика~25 минутНовичок

Когда разбирали циклы, вы уже перебирали числа через 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() цикл по словарю всегда отдаёт только ключи. Если нужны значения — уточняйте это явно.

Что важно запомнить

1.
for элемент in коллекция: — универсальная формула для списка, кортежа, строки и (с оговорками) словаря. Индекс для этого не нужен.
2.
Кортеж перебирается так же, как список — отличие только в том, что его содержимое нельзя менять.
3.
enumerate(коллекция) добавляет к перебору порядковый номер каждого элемента, начиная с 0 (или с числа из start).
4.
Словарь без уточнения перебирается по ключам. Для значений берите .values(), для пар «ключ, значение» — .items().
5.
Не меняйте список во время его перебора — удаление или добавление элементов сбивает внутренний счётчик цикла.

Проверьте себя

5 вопросов

Сумма чётных чисел

Дан список чисел. Напишите программу, которая с помощью цикла for находит сумму всех чётных чисел этого списка.

numbers = [12, 7, 24, 9, 18, 5, 30, 11]

Результат сохраните в переменную total и выведите в формате: Сумма чётных чисел: ...

Слова длиннее пяти букв

Premium

Среднее, минимум и максимум без встроенных функций

Premium