Ответ
Это два разных, но связанных понятия в протоколе итерации Python.
-
Итерируемый объект (Iterable) Это любой объект, который может вернуть итератор. Он определяет метод
__iter__()
, который возвращает новый объект-итератор. Итерируемые объекты можно использовать в циклеfor ... in ...
. Примеры: списки (list
), кортежи (tuple
), строки (str
), словари (dict
). -
Итератор (Iterator) Это объект, который представляет поток данных и управляет процессом итерации. Он определяет метод
__next__()
, который возвращает следующий элемент и вызывает исключениеStopIteration
, когда элементы заканчиваются. Итератор также должен иметь метод__iter__()
, возвращающий самого себя.
Ключевое отличие
Итерируемый объект — это "источник" данных, а итератор — это "помощник", который отслеживает текущую позицию при переборе этих данных.
Характеристика | Итерируемый объект (Iterable) | Итератор (Iterator) |
---|---|---|
Основной метод | __iter__() |
__next__() и __iter__() |
Состояние | Не хранит состояние итерации | Хранит состояние (текущий элемент) |
Назначение | Предоставить данные для перебора | Управлять процессом перебора |
Практический пример
Цикл for
в Python неявно выполняет следующие шаги:
- Вызывает
iter()
у итерируемого объекта (my_list
), чтобы получить итератор. - В каждой итерации вызывает
next()
у итератора, чтобы получить следующий элемент. - Перехватывает исключение
StopIteration
для завершения цикла.
# 1. Итерируемый объект (источник данных)
my_list = [10, 20, 30]
# 2. Получение итератора из итерируемого объекта
my_iterator = iter(my_list)
# my_iterator - это итератор, он хранит состояние
# type(my_list) -> <class 'list'>
# type(my_iterator) -> <class 'list_iterator'>
# 3. Ручной перебор с помощью итератора
print(next(my_iterator)) # Вывод: 10
print(next(my_iterator)) # Вывод: 20
print(next(my_iterator)) # Вывод: 30
# Следующий вызов вызовет исключение StopIteration
# print(next(my_iterator)) # -> StopIteration
Таким образом, любой итератор является итерируемым объектом, но не наоборот.