Итераторы в Python
Итератор можно представить как объект со счётным набором значений, которые можно перебирать по одному, пока вы не пройдёте их все.
Объект становится итератором в Python благодаря правилу, которое называется протоколом итератора: объект должен предоставлять два метода, __iter__() и __next__().
Итератор и итерируемый объект
Список, кортеж, словарь или множество — это итерируемый объект: контейнер, который может выдать вам итератор, когда вы его запросите.
Чтобы запросить итератор, передайте контейнер встроенной функции iter():
Пример
iter() и next().
Создайте кортеж с "apple", "banana", "cherry".
Вывод: полная программа на Python
mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)
print(next(myit))
print(next(myit))
print(next(myit))
Пример
iter() и next().
Выведите каждый символ по одному.
Вывод: полная программа на Python
mystr = "banana"
myit = iter(mystr)
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
Перебор итератора в цикле
Цикл for — более короткий способ пройти по любому итерируемому объекту:
Пример
Вывод: полная программа на Python
mytuple = ("apple", "banana", "cherry")
for x in mytuple:
print(x)
Пример
Вывод: полная программа на Python
mystr = "banana"
for x in mystr:
print(x)
Создание итератора
Ваш собственный класс становится итератором, как только вы добавите в него оба метода: __iter__() и __next__().
В главе «Классы/объекты в Python» объясняется __init__() — функция, которая есть у каждого класса и нужна для подготовки в момент создания объекта.
__iter__() играет похожую роль: он может выполнять подготовительную работу, но возвращать всегда должен сам объект-итератор.
__next__() тоже может выполнять операции, и каждый его вызов должен возвращать следующий элемент последовательности.
Пример
MyNumbers, который реализует __iter__() и __next__().
Итератор возвращает числа, начиная с 1, каждый раз увеличивая значение на единицу.
Выведите первые 5 значений с помощью next().
Вывод: полная программа на Python
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
StopIteration
Итератор из предыдущего примера ничто не останавливает: при достаточном количестве вызовов next() или внутри цикла for он никогда бы не закончился.
Завершить его позволяет исключение StopIteration.
Добавьте в __next__() условие, которое вызывает это исключение, когда итерация выполнится нужное вам количество раз:
Пример
MyNumbers с методами __iter__() и __next__(), который возвращает числа от 1 до 20.
Используйте StopIteration, чтобы остановиться после 20 итераций. Выведите все значения с помощью цикла for.
Вывод: полная программа на Python
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)