Что такое итератор в Python
Итератор в Python — это объект, который реализует протокол итераторов, состоящий из методов __iter__() и __next__(), и позволяет последовательно получать элементы из коллекции или другого итерируемого объекта. Итератор запоминает текущее состояние итерации, при вызове next() возвращает следующий элемент, а когда элементы заканчиваются, выбрасывает исключение StopIteration.
Как это работает
Протокол итераторов требует реализации двух методов:
__iter__()— возвращает сам объект итератора. Этот метод вызывается функциейiter().__next__()— возвращает следующий элемент последовательности. Если элементов больше нет, метод должен выброситьStopIteration. Этот метод вызывается функциейnext().
Итератор отличается от итерируемого объекта: итерируемый объект (например, список, кортеж, словарь) имеет метод __iter__(), но не обязательно __next__(). Итератор же — это объект, который уже находится в процессе перебора и хранит состояние.
Пример
numbers = [1, 2, 3]
iter_obj = iter(numbers) # создаёт итератор из списка
print(next(iter_obj)) # 1
print(next(iter_obj)) # 2
print(next(iter_obj)) # 3
# next(iter_obj) вызовет StopIteration, так как элементы закончилисьЦикл for автоматически использует протокол итераторов: он вызывает iter() для получения итератора и затем многократно вызывает next(), пока не получит StopIteration. Это делает итераторы основой для перебора любых коллекций в Python.
Подводные камни
- Итератор одноразовый: после того как он исчерпан, повторное использование невозможно. Нужно создавать новый итератор через
iter(). - Не все итерируемые объекты являются итераторами. Например, список — итерируемый, но не итератор: у него нет метода
__next__(). Проверить это можно с помощьюhasattr(obj, '__next__'). - Генераторы — это частный случай итераторов, создаваемых с помощью функций с
yield. Они автоматически реализуют протокол итераторов. - При создании собственного итератора важно правильно выбрасывать
StopIterationв__next__(), иначе циклы будут работать бесконечно.
Когда использовать
Итераторы применяются везде, где нужен последовательный перебор элементов: в циклах for, в генераторных выражениях, при работе с большими данными (например, чтение файлов построчно), в функциях map(), filter() и других. Собственные итераторы полезны, когда нужно реализовать нестандартную логику перебора или работать с бесконечными последовательностями.
Коротко
- Итератор — объект с методами
__iter__()и__next__(), который хранит состояние перебора. next()возвращает следующий элемент или выбрасываетStopIteration.- Цикл
forавтоматически использует итераторы. - Итератор одноразовый, а генераторы — удобный способ создания итераторов.
