Python: уроки, справочник и задачи

enumerate(): нумерация элементов при переборе

Раздел: Списки, кортежи и множества · Обновлено 31.10.2026

Функция enumerate в Python выдает при переборе пары из номера и самого элемента, поэтому индекс не нужно считать вручную. Ниже разобраны синтаксис и параметр start, перебор списков, строк, словарей и файлов, сочетание с zip() и генераторами, а также ошибки, которые встречаются у начинающих.

enumerate(): нумерация элементов при переборе
Фото: Dietmar Rabich / CC BY-SA 4.0, Wikimedia Commons
Содержание статьи
  1. Синтаксис и что возвращает enumerate()
  2. Нумерация в цикле for
    1. Счет с единицы
    2. Почему не range(len())
  3. Изменение элементов списка по индексу
  4. Строки, словари и файлы
  5. Связка с zip() и генераторами
  6. Частые вопросы
    1. Как начать нумерацию с 1?
    2. Как перебрать список с конца с правильными индексами?
    3. Можно ли получить элемент по номеру из enumerate()?
    4. Замедляет ли enumerate() цикл?

Синтаксис и что возвращает enumerate()

Функция встроенная и принимает два аргумента:

enumerate(iterable, start=0)

Результат это ленивый итератор, который на каждом шаге отдает кортеж (номер, элемент). Чтобы увидеть все пары сразу, его превращают в список.

languages = ['Python', 'Java', 'Go']
pairs = enumerate(languages)
print(pairs)        # <enumerate object at 0x...>
print(list(pairs))  # [(0, 'Python'), (1, 'Java'), (2, 'Go')]
print(list(pairs))  # []  итератор уже пройден

Как и другие итераторы, объект enumerate одноразовый: после полного прохода он пуст. Если пары нужны несколько раз, сохраните их в список или вызовите enumerate() заново.

Нумерация в цикле for

Основной сценарий: перебрать коллекцию и одновременно знать номер текущего элемента. Кортеж сразу распаковывается в две переменные. Как устроены распаковка и сам цикл, описано в статье про цикл for.

grocery = ['хлеб', 'молоко', 'масло']
for index, item in enumerate(grocery):
    print(index, item)
# 0 хлеб
# 1 молоко
# 2 масло

Счет с единицы

Для вывода пользователю нумерация с нуля выглядит странно. Параметр start сдвигает только номер, элементы и их настоящие индексы в списке не меняются.

tasks = ['Купить продукты', 'Позвонить маме', 'Сдать отчет']
for num, task in enumerate(tasks, start=1):
    print(f"{num}. {task}")
# 1. Купить продукты
# 2. Позвонить маме
# 3. Сдать отчет

Почему не range(len())

Тот же результат можно получить через for i in range(len(tasks)) и обращение tasks[i]. Такой код длиннее, хуже читается и работает только с коллекциями, у которых есть индексы и длина. enumerate() подходит для любых итерируемых объектов, включая генераторы и файлы, у которых len() нет.

ЗадачаВариант с range(len())Вариант с enumerate()
Номер и элементfor i in range(len(a)): x = a[i]for i, x in enumerate(a):
Нумерация с 1print(i + 1, a[i])enumerate(a, start=1)
Генератор или файлНе работаетРаботает

Вариант с range(len()) оправдан, когда сам элемент не нужен, а нужны только позиции, например при обмене соседних элементов. Но и для сравнения пар соседей часто короче записать zip(a, a[1:]).

Изменение элементов списка по индексу

Переменная цикла это копия ссылки, и присваивание ей нового значения список не меняет. Чтобы заменить элемент на месте, нужен индекс, и enumerate() его дает.

prices = [100, 250, 80, 400]
for i, price in enumerate(prices):
    if price > 200:
        prices[i] = round(price * 0.9)
print(prices)  # [100, 225, 80, 360]

Не удаляйте элементы из списка во время такого перебора: индексы сдвигаются, и часть элементов будет пропущена. Для отбора лучше построить новый список.

Строки, словари и файлы

Функция работает с любой коллекцией, но результат зависит от того, что именно отдает объект при переборе.

word = 'мама'
print([i for i, ch in enumerate(word) if ch == 'а'])  # [1, 3]

scores = {'Анна': 92, 'Борис': 78}
for place, (name, score) in enumerate(scores.items(), start=1):
    print(place, name, score)
# 1 Анна 92
# 2 Борис 78

У словаря без items() перебираются только ключи. Обратите внимание на скобки при распаковке: пара из items() вложена в кортеж от enumerate(), поэтому пишем place, (name, score).

При чтении файла построчно номер строки помогает в сообщениях об ошибках. Файл не загружается в память целиком, строки читаются по одной. Подробнее о режимах открытия написано в материале о чтении и записи файлов.

with open('config.txt', encoding='utf-8') as f:
    for line_no, line in enumerate(f, start=1):
        if '=' not in line:
            print(f"Строка {line_no}: нет знака равенства")

Связка с zip() и генераторами

Когда нужно идти по двум спискам сразу и знать номер шага, zip() вкладывают в enumerate(). Подробно о параллельном переборе рассказано в статье про zip и map.

names = ['Анна', 'Борис', 'Вера']
ages = [25, 31, 28]
for i, (name, age) in enumerate(zip(names, ages), start=1):
    print(i, name, age)
# 1 Анна 25
# 2 Борис 31
# 3 Вера 28

menu = dict(enumerate(['Новая игра', 'Загрузить', 'Выход'], start=1))
print(menu)  # {1: 'Новая игра', 2: 'Загрузить', 3: 'Выход'}

index_of = {name: i for i, name in enumerate(names)}
print(index_of['Вера'])  # 2

Последний пример строит обратный индекс: по значению сразу получаем позицию, не вызывая медленный list.index() в цикле. Такие однострочники строятся по правилам генераторов, которые разобраны в статье про list comprehension. Полное описание функции есть в документации Python.

Частые вопросы

Ответы на вопросы, которые возникают при использовании enumerate().

Как начать нумерацию с 1?

Передайте второй аргумент: enumerate(items, 1) или enumerate(items, start=1). Именованная форма читается понятнее.

Как перебрать список с конца с правильными индексами?

Оберните результат в reversed(list(enumerate(items))). Сам объект enumerate не поддерживает reversed(), поэтому его сначала превращают в список.

Можно ли получить элемент по номеру из enumerate()?

Нет, это итератор без индексации, запись enumerate(a)[0] вызовет TypeError. Для доступа по номеру обращайтесь к исходному списку.

Замедляет ли enumerate() цикл?

Разница с ручным счетчиком минимальна, а по сравнению с range(len()) и обращением по индексу enumerate() обычно даже немного быстрее.