В Python Итерируемый объект (iterable) — это объект, который можно "перебрать", то есть последовательно получать из него элементы один за другим. Это фундаментальная концепция в Python, лежащая в основе циклов for и многих других операций.
Проще говоря, если вы можете использовать объект в цикле for … in…, то это итерируемый объект.
Что делает объект итерируемым?
Объект считается итерируемым, если он реализует один из следующих методов:
__iter__(): Должен возвращать объект-итератор. __getitem__(): Должен принимать целочисленные индексы (начиная с 0) и возбуждать IndexError при выходе за границы. (Хотя __getitem__ технически делает объект итерируемым, современный подход предпочитает __iter__.)
Большинство встроенных типов данных в Python являются итерируемыми:
- Списки (List): [1, 2, 3] Кортежи (Tuple): (1, 2, 3) Строки (Str): "hello" Словари (Dict): { ‘a’: 1, ‘b’: 2 } (итерируются по ключам) Множества (Set): {1, 2, 3} Объекты Range: range(5) Файловые объекты: Когда вы открываете файл (open(…)), вы можете итерироваться по его строкам.
Итерируемый объект vs Итератор
Это два тесно связанных, но разных понятия:
- Итерируемый объект (Iterable): Объект, который Может быть перебран. Он предоставляет Итератор (iterator).
- Пример: список [1, 2, 3] является итерируемым объектом. Когда вы пишете for item in my_list:, Python неявно вызывает iter(my_list) (что эквивалентно my_list.__iter__()), чтобы получить итератор.
Итератор (Iterator): Объект, который Выполняет перебор. Он сохраняет свое внутреннее состояние (где он находится в последовательности) и реализует следующие методы:
- __next__(): Должен возвращать следующий элемент последовательности. Если элементов больше нет, он должен возбуждать исключение StopIteration. __iter__(): Должен возвращать сам себя (то есть, итератор также является итерируемым объектом, но уже "готовым к перебору").
Пример взаимосвязи:
Python
My_list = [10, 20, 30] # Это ИТЕРИРУЕМЫЙ ОБЪЕКТ
# Получаем итератор из итерируемого объекта
My_iterator = iter(my_list) # Эквивалентно my_list.__iter__()
Print(my_iterator) # Вывод: <list_iterator object at 0x…>
# Получаем элементы из итератора с помощью next()
Print(next(my_iterator)) # Вывод: 10
Print(next(my_iterator)) # Вывод: 20
Print(next(my_iterator)) # Вывод: 30
# Попытка получить следующий элемент после исчерпания итератора
Try:
print(next(my_iterator))
Except StopIteration:
print("Элементов больше нет (StopIteration)")
Почему это важно?
Эффективность памяти (ленивая загрузка): Итераторы позволяют работать с очень большими последовательностями данных, не загружая их целиком в память. Например, при чтении большого файла вы итерируетесь по строкам, а не загружаете весь файл сразу. Унифицированный доступ: Цикл for может работать с любым итерируемым объектом, не беспокоясь о том, как внутренне хранятся данные (список, кортеж, файл, генератор и т. д.). Генераторы: Генераторы в Python — это самый простой способ создания итераторов. Функция, которая содержит ключевое слово yield, становится функцией-генератором и при вызове возвращает объект-генератор (который сам по себе является итератором).
Python
Def my_generator():
yield 1
yield 2
yield 3
Gen = my_generator() # gen — это объект-генератор (и итератор)
Print(next(gen)) # Вывод: 1
Print(next(gen)) # Вывод: 2
For item in my_generator(): # Здесь my_generator() вызывается, чтобы получить новый итератор
print(item)
# Вывод:
# 1
# 2
# 3
Создание собственных итерируемых объектов
Вы можете создавать свои собственные классы, которые являются итерируемыми, реализуя метод __iter__().
Python
Class MyCustomRange:
def __init__(self, start, end):
self. start = start
self. end = end
def __iter__(self):
# Этот метод должен возвращать объект-итератор.
# В данном случае, мы можем просто использовать генератор.
current = self. start
while current < self. end:
yield current # yield делает эту функцию генератором, который является итератором
current += 1
# Использование нашего пользовательского итерируемого объекта
For num in MyCustomRange(1, 5):
print(num)
# Вывод:
# 1
# 2
# 3
# 4
# Или используя iter() и next()
My_range_iter = iter(MyCustomRange(10, 13))
Print(next(my_range_iter)) # Вывод: 10
Print(next(my_range_iter)) # Вывод: 11
Print(next(my_range_iter)) # Вывод: 12
Понимание итерируемых объектов и итераторов является ключом к написанию эффективного и идиоматического Python-кода, особенно при работе с большими объемами данных и в асинхронном программировании.