Если вы здесь, значит уже использовали range(len()), знакомы с циклами, и, наверняка, успешно применяете их для решения разных задач. Но совершенству нет предела, а enumerate() в Python поможет к нему приблизиться.
С enumerate() циклы потребляют меньше памяти и становятся читабельнее, а сама функция работает с самыми разными итераторами.
В этой статье мы разберёмся в синтаксисе функции enumerate(), посмотрим как она работает и когда применяется. Мы сравним циклы с enumerate и range(len()) и узнаем, почему range(len()) зачастую может быть антипаттерном.
Что такое enumerate в Python
enumerate() — это встроенная функция, которая принимает итерируемый объект (список, строку, кортеж, и др.) и возвращает итератор кортежей вида (индекс, элемент). Если проще, enumerate в Python принимает объект с элементами, а возвращает новый объект с элементами старого, у которых есть индексы.
Если в цикле for обернуть в enumerate перебираемый (или итерируемый) объект, enumerate() добавит к элементам индексы и вернёт новый объект, с проиндексированными элементами, по которым можно пройти в цикле.
Код с enumerate в цикле может выглядеть, например, так:
fruits = ["яблоко", "банан", "вишня"]
for index, fruit in enumerate(fruits):
print(index, fruit)
К этому примеру мы ещё вернёмся, а пока разберёмся с синтаксисом.
Синтаксис функции enumerate()
Функция enumerate() принимает два аргумента: iterable и start, параметр start при этом необязательный.
enumerate(iterable, start=0)
iterable — это тот самый итерируемый объект элементам которого будут присвоены индексы.
start — это число, с которого enumerate начинает индексы для элементов. Если этот параметр не задать, то индексы начинаются с нуля.
В следующем куске кода мы не будем задавать параметр start и он будет равен нулю:
fruits = ["яблоко", "банан", "вишня"]
print(list(enumerate(fruits)))
# Выведет [(0, 'яблоко'), (1, 'банан'), (2, 'вишня')]
Или, например, зададим:
fruits = ["яблоко", "банан", "вишня"]
print(list(enumerate(fruits, 1)))
# Выведет [(1, 'яблоко'), (2, 'банан'), (3, 'вишня')]
Теперь подробнее поговорим о том как работает enumerate и как это работает в циклах.
Полезный блок со скидкой
Если тема зашла и хочется войти в ИТ или повысить свой грейд, — держите промокод Практикума на любой платный курс: по ссылке (можно просто нажать). Он даст скидку 15% при покупке и позволит сэкономить на обучении — но только до 30 апреля.
Как работает enumerate в Python
Как вы видите, использовать enumerate() сам по себе довольно просто. Давайте разберёмся как работать с этой функцией в цикле.
Попробуем вывести пронумерованный список фруктов для пользователя. Посмотрите на этот кусочек кода:
fruits = ["яблоко", "банан", "вишня"]
for index, fruit in enumerate(fruits, 1):
print(index, fruit)
В этом коде enumerate() принимает список fruits и возвращает объект, в котором лежат кортежи из пар (индекс, фрукт).
На каждой итерации мы обращаемся к кортежу и сразу имеем доступ к индексу фрукта и самому фрукту, затем выводим их. Это повторяется пока не закончатся кортежи. В итоге мы получим список:
1 яблоко
2 банан
3 вишня
Параметр start
Если бы мы не задали параметр start=1 в примере выше, то нумерация началась бы с нуля. Но мы задали его явно равным единице и получили список, пронумерованный в более читаемом для человека формате.
Параметр start не обязательно равен только нулю или единице. Его можно можно задать произвольно. 3, 5, 7, 999? Без разницы, зависит от того, что нужно вам для решения конкретной задачи.
Что возвращает enumerate()
Функция enumerate() возвращает специальный объект enumerate, который содержит в себе кортежи, внутри которых значения с индексами. Как мы уже видели, эти кортежи можно перебирать в цикле и иметь прямой доступ к индексу и соответствующему элементу. А вот если попытаться вывести такой объект вы увидите интересное:
fruits = ["яблоко", "банан", "вишня"]
print(enumerate(fruits))
# Выведет <enumerate object at 0x7f7b7be2a1b0>
Для того чтобы, например, полностью вывести такой объект его нужно преобразовать. Можем сделать его списком:
fruits = ["яблоко", "банан", "вишня"]
print(list(enumerate(fruits)))
# Выведет [(0, 'яблоко'), (1, 'банан'), (2, 'вишня')]
Имейте в виду этот нюанс при работе с enumerate.
Практические примеры
Поговорить поговорили, теперь можно и посмотреть на примеры.
Перебор списка с индексами
Похожее уже было у нас в примерах выше, это просто другой пример. В нём мы пронумеруем шаги работы воображаемого программиста и выведем этот список пользователю.
tasks = ['Кодить', 'Тестить', 'Коммитить']
for index, task in enumerate(tasks, 1):
print(f"Шаг {index}: {task}")
Получим:
Шаг 1: Кодить
Шаг 2: Тестить
Шаг 3: Коммитить
enumerate со строками
Мы уже обсуждали, что enumerate() работает с самыми разными итераторами. Строки — один из них. В этом примере мы пронумеруем буквы слова и для наглядности выведем.
word = "КОД"
for i, letter in enumerate(word):
print(f"{i}: {letter}")
Получим:
0: К
1: О
2: Д
Это может быть полезно, если нужно разобрать или изменить слово, найти в нём определённые символы и так далее.
Нумерация строк файла
Файлы — ещё один вид итераторов, с которыми может работать enumerate(). Здесь мы создадим файл с двумя строчками. Мы разберём файл на строки и выведем их. В код создания файла можете не вникать, а можете погуглить и вникнуть!
# Создадим для нашего пример файл с двумя строчками
with open('test.txt', 'w') as f:
f.write('Строка 1\nСтрока 2\n')
# Откроем файл, пронумеруем строки и выведем
with open('test.txt', 'r') as f:
for i, line in enumerate(f, start=1):
print(f"{i}: {line.strip()}")
Получим:
1: Строка 1
2: Строка 2
Работа с файлами — важная штука. Когда нужно обработать какие-то логи или какой-то документ, просто позовите enumerate() и эта прекрасная функция вам обязательно поможет.
Создание словаря через enumerate
enumerate может здорово помочь не только когда нужно что-то разобрать, но и собрать. Давайте создадим словарь:
labels = ['CPU', 'RAM']
mapping = dict(enumerate(labels, start=1))
print(mapping)
Получим:
{1: 'CPU', 2: 'RAM'}
enumerate() или range(len())?
Обе конструкции вполне себе помогают нам перебирать элементы в циклах. Почему же тогда говорят, что range(len()) — это антипаттерн? И имеет ли эта конструкция право на жизнь? Для того, чтобы разобраться, вернёмся к нашим фруктам. В следующем фрагменте кода оба цикла выведут одно и то же, тогда в чём же разница?
items = ["яблоко", "банан", "вишня"]
for index, item in enumerate(items):
print(index, item)
for index in range(len(items)):
print(index, items[index])
Дело в том, что range(len(items) возвращает только индексы и вынуждает дополнительно обращаться по индексу к самому итератору items[index]. Это происходит несколько медленнее, чем в случае с enumerate, и при этом хуже читается из-за не очень интуитивной записи и скобок.
При этом у range(len()) есть и свои случаи применения, для которых enumerate() не подойдёт. Если нужно пройти итератор с конца или с нестандартным шагом (например, не +1, а +2), или нужны только индексы, но не нужны значения, то range(len()) подойдёт лучше.
Типичные ошибки при работе с enumerate()
Как и с любой другой функцией или структурой данных в программировании есть типичные ошибки, которые совершают при работе с enumerate().
1. enumerate не распакован
Если в цикле не распаковать результат работы enumerate, то перебираться будут кортежи, а не индексы и значения, а, значит, ваш скрипт сработает неправильно.
fruits = ["яблоко", "банан", "вишня"]
for fruit in enumerate(fruits): # Ошибка, перебираются значения вместе с индексами
print(fruit)
Получим:
(0, ‘яблоко’)
(1, ‘банан’)
(2, ‘вишня’)
for index, fruit in enumerate(fruits): # Правильно, индекс и значение будут отдельно
print(index, fruit)
Получим:
0 яблоко
1 банан
2 вишня
2. Нарушен порядок переменных в цикле
С распаковкой самой по себе разобрались, но чаще о ней не забывают, а путают порядок переменных. Помните, первым идёт индекс, если их перепутать, то внутри цикла вы будете обрабатывать не то, что ожидаете.
fruits = ["яблоко", "банан", "вишня"]
for fruit, index in enumerate(fruits): # Ошибка, в index будет находиться значение, а не индекс
print(index, fruit)
Получим:
яблоко 0
банан 1
вишня 2
for index, fruit in enumerate(fruits): # Правильно, теперь всё на своих местах
print(index, fruit)
Получим:
0 яблоко
1 банан
2 вишня
3. Параметр start потерялся
Мы разбирали с вами синтаксис enumerate() и параметр start. Про него довольно легко забыть, потому что и без него функция сработает. Только индекс по умолчанию = 0, если в вашей программе нужно начать с другого индекса и вы о нём забыли, это может привести не к тому результату.
fruits = ["яблоко", "банан", "вишня"]
for fruit, index in enumerate(fruits): # Ошибка, index начнётся с нуля
print(index, fruit)
Получим:
яблоко 0
банан 1
вишня 2
for index, fruit in enumerate(fruits, 3): # Правильно, нумерация идёт с нужного числа
print(index, fruit)
Получим:
3 яблоко
4 банан
5 вишня
В этой статье мы разобрались как работает enumerate() в Python и в каких случаях без range(len()) всё-таки никак не обойтись. Надеемся, что примеры помогли во всём разобраться, теперь самое время применить enumerate() в своём коде и продолжать грызть гранит программирования.
Советуем дополнительно по теме:
- Python-стек в 2026: что реально используют разработчики — после базовых функций — понять, что вообще нужно знать Python-разработчику на рынке прямо сейчас.
- 12 библиотек Python, которые стоит попробовать в 2026 году — enumerate — встроенная функция, но реальные проекты строятся на библиотеках.
- Бэкенд с нуля в 2026: учим Flask, Docker, Redis и ещё 7 технологий — роадмап для тех, кто изучает Python и хочет понять, куда двигаться дальше.
Полезный блок со скидкой
Если вам интересно погрузиться в мир ИТ и при этом немного сэкономить, держите наш промокод на курсы Практикума, он даст вам скидку при оплате.
Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям, начать можно в любой момент, карту привязывать не нужно, если что.
