Как отличить итератор от объекта, поддерживающего протокол итерации?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Итератор — это объект, который хранит состояние обхода и умеет возвращать элементы по одному. Объект, поддерживающий протокол итерации, — это более широкий случай: он умеет создать итератор через __iter__(). На практике итератор всегда итерируемый, но не каждый итерируемый объект является итератором.
Определение:
В Python итерируемый объект — это объект, по которому можно пройти в цикле for. Для этого у него должен быть метод __iter__(), возвращающий итератор, либо старый вариант — __getitem__() с индексами от 0.
Итератор — это объект с двумя обязательными свойствами: он возвращает следующий элемент через __next__() и сам себя возвращает в __iter__(). Когда элементы заканчиваются, он возбуждает StopIteration.
Проще говоря: итерируемый объект можно “запустить” в обход, а итератор уже сам хранит текущее место обхода.
Пример использования:
# Итерируемый объект, но не итератор
lst = [1, 2, 3]
it = iter(lst) # получаем итератор
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
# Сам список можно итерировать заново:
print(list(lst)) # [1, 2, 3]
Пояснение кода:
lst— это список, то есть итерируемый объект.- Вызов
iter(lst)создает из списка итератор. next(it)последовательно забирает элементы из итератора.- Когда элементы заканчиваются, следующий
next(it)вызоветStopIteration. - Сам список не “расходуется” и может быть итерирован повторно, потому что он не хранит текущее состояние обхода как итератор.
Если нужен прямой пример разницы через встроенные проверки:
lst = [1, 2, 3]
it = iter(lst)
print(hasattr(lst, "__iter__")) # True
print(hasattr(lst, "__next__")) # False
print(hasattr(it, "__iter__")) # True
print(hasattr(it, "__next__")) # True
Ключевые моменты:
- Итерируемый объект отвечает на вопрос: “можно ли по нему пройтись?”
- Итератор отвечает на вопрос: “как получить следующий элемент прямо сейчас?”
forсначала вызываетiter(...), а затем многократноnext(...).- Итератор — это одноразовое состояние обхода; после завершения его обычно нельзя “перемотать” без создания нового.
- Все итераторы являются итерируемыми, но не все итерируемые объекты являются итераторами.
- Типичный итерируемый объект: список, строка,
dict; типичный итератор: результатiter(...), генератор.