- Назначение enumerate
enumerate() — встроенная функция Python для итерируемых объектов.
Задача:
- получить индекс элемента
- и сам элемент одновременно
- без ручного счётчика
⸻
- Сигнатура
enumerate(iterable, start=0)
Параметры:
- iterable — любой итерируемый объект (list, tuple, str, dict, generator)
- start — начальное значение индекса (по умолчанию 0)
Возвращает:
- объект enumerate (итератор)
⸻
- Базовый пример
items = ['a', 'b', 'c']
for index, value in enumerate(items):
print(index, value)
Результат:
0 a
1 b
2 c
⸻
- С параметром start
for index, value in enumerate(items, start=1):
print(index, value)
Результат:
1 a
2 b
3 c
⸻
- Внутреннее поведение
enumerate эквивалентен:
def my_enumerate(iterable, start=0):
i = start
for item in iterable:
yield i, item
i += 1
⸻
- Работа с разными типами
6.1 Список
lst = [10, 20, 30]
for i, v in enumerate(lst):
print(i, v)
6.2 Строка
s = "abc"
for i, ch in enumerate(s):
print(i, ch)
6.3 Словарь
d = {'x': 1, 'y': 2}
for i, key in enumerate(d):
print(i, key, d[key])
⸻
- Преобразование в список
list(enumerate(['a', 'b']))
Результат:
[(0, 'a'), (1, 'b')]
⸻
- Использование без распаковки
e = enumerate(['a', 'b'])
print(next(e)) # (0, 'a')
print(next(e)) # (1, 'b')
⸻
- Частые сценарии
9.1 Индексация при фильтрации
data = [5, 10, 15]
for i, v in enumerate(data):
if v > 8:
print(i, v)
9.2 Изменение элементов списка
lst = [1, 2, 3]
for i, v in enumerate(lst):
lst[i] = v * 2
⸻
- Альтернатива без enumerate
for i in range(len(items)):
print(i, items[i])
Минусы:
- менее читаемо
- больше кода
- риск ошибок при изменении структуры
⸻
- Комбинация с другими функциями
11.1 С zip
a = ['x', 'y']
b = [1, 2]
for i, (x, y) in enumerate(zip(a, b)):
print(i, x, y)
⸻
- Ошибки
12.1 Неправильная распаковка
for x in enumerate([1,2,3]):
print(x)
Результат:
(0,1)
(1,2)
(2,3)
Решение:
for i, v in enumerate([1,2,3]):
...
⸻
12.2 Попытка изменить индекс
for i, v in enumerate(lst):
i = 10 # не влияет на enumerate
Индекс — копия, не ссылка.
⸻
- Производительность
- enumerate быстрее и безопаснее ручного счётчика
- не создаёт промежуточные списки
- работает лениво (lazy iterator)
⸻
- Когда использовать
Использовать:
- нужен индекс + значение
- проход по коллекции
Не использовать:
- индекс не нужен
- работаешь с генераторами, где индекс не имеет смысла
⸻
- Итог
enumerate:
- упрощает код
- снижает ошибки
- улучшает читаемость
- стандарт де-факто для индексации в циклах