Введение в итераторы Python

Что такое итераторы? Итератор в Python относится к объекту, по которому мы можем выполнять итерацию. Итератор состоит из счетных значений, и эти значения можно просматривать одно за другим. Итератор просто реализует протокол итератора Python. Протокол итератора - это класс Python, который имеет два специальных метода, а именно __iter __ () и __next __ (). С помощью этих двух методов итератор может вычислить следующее значение в итерации. С итераторами нам легко

Что такое итераторы?

Итератор в Python относится к объекту, по которому мы можем выполнять итерацию. Итератор состоит из счетных значений, и эти значения можно просматривать одно за другим.

Итератор просто реализует протокол итератора Python. Протокол итератора

  • это класс Python, который имеет два специальных метода, а именно __iter__() и __next__() . С помощью этих двух методов итератор может вычислить следующее значение в итерации.

С итераторами нам легко работать с последовательностями элементов в Python. Нам не нужно выделять вычислительные ресурсы всем элементам в последовательности, мы выполняем итерацию по одному элементу за раз, что помогает нам сэкономить место в памяти.

В этой статье мы изучим, как работать с итераторами в Python.

Итерируемые объекты в Python

Итерируемый объект - это объект, способный возвращать итератор. Итерируемый объект может представлять как конечные, так и бесконечные источники данных. Итерация прямо или косвенно реализует два метода: __iter__() и __next__() . Метод __iter__() возвращает объект-итератор, а метод __next__() помогает нам перемещаться по элементам в итеративном объекте.

Примеры итерируемых объектов в Python включают списки, словари, кортежи и наборы.

Создание итератора

В Python мы создаем итератор, реализуя для __iter__() и __next__() . Рассмотрим следующий пример:

 class IterationExample: 
 def __iter__(self): 
 self.x = 0 
 return self 
 
 def __next__(self): 
 y = self.x 
 self.x += 1 
 return y 
 
 classinstance = IterationExample() 
 element = iter(classinstance) 

Мы создали итератор с именем element который печатает числа от 0 до N. Сначала мы создали экземпляр класса и дали ему имя classinstance . Затем мы вызвали iter() и передали имя экземпляра класса в качестве параметра. Это создает объект-итератор.

Давайте теперь обсудим, как использовать итератор для фактического перебора элементов.

Итератор

Метод next() помогает нам перебирать элементы итератора. Продемонстрируем это на примере, приведенном выше:

 class IterationExample: 
 def __iter__(self): 
 self.x = 0 
 return self 
 
 def __next__(self): 
 y = self.x 
 self.x += 1 
 return y 
 
 classinstance = IterationExample() 
 element = iter(classinstance) 
 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 
 print(next(element)) 

Выход

 0 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 

В приведенном выше скрипте мы вызвали метод next() и передали ему имя элемента итератора в качестве параметра. Каждый раз, когда мы это делаем, итератор переходит к следующему элементу в последовательности. Вот еще один пример:

 # create a list 
 list1 = [0, 5, 10, 15] 
 
 # create an iterator 
 element = iter(list1) 
 
 ## use next() to traverse/iterate through the list elements 
 
 # prints first element, 0 
 print(next(element)) 
 
 # prints second element, 5 
 print(next(element)) 
 
 ## next(element) is similar to element.__next__() 
 
 # prints third element, 10 
 print(element.__next__()) 
 
 # prints fourth element, 15 
 print(element.__next__()) 

Выход

 0 
 5 
 10 
 15 

В приведенном выше сценарии мы создали список с именем list1 , который содержит 4 целых числа. Создан итератор с именем element . Метод next() помог нам перебрать элементы списка.

Итерация с помощью цикла "for"

Цикл for помогает нам перебирать любой объект, способный возвращать итератор. Например:

 # create a list 
 list1 = [0, 5, 10, 15] 
 
 # create an iterator 
 element = iter(list1) 
 
 # iterate with a for loop 
 for x in element: 
 print(x) 

Выход

 0 
 5 
 10 
 15 

В приведенном выше коде мы создали переменную с именем x , которая используется для перебора element итератора через цикл for

Бесконечные итераторы

Бесконечный итератор - это итератор с бесконечным числом итераций. Мы должны быть особенно осторожны при работе с бесконечными итераторами. Рассмотрим следующий пример:

 class IterationExample: 
 def __iter__(self): 
 self.x = 0 
 return self 
 
 def __next__(self): 
 y = self.x 
 self.x += 1 
 return y 
 
 classinstance = IterationExample() 
 element = iter(classinstance) 
 
 for x in element: 
 print(x) 

Приведенный выше код будет работать вечно. Чтобы остановить это, вам придется вмешаться вручную. Вот еще один пример, демонстрирующий, как создать бесконечный итератор в Python:

 class Infinite: 
 # Print all even numbers 
 
 def __iter__(self): 
 self.x = 0 
 return self 
 
 def __next__(self): 
 x = self.x 
 self.x += 2 
 return x 

Код должен возвращать все четные числа, начиная с 0. Мы можем запустить код, как показано ниже:

 >>> y = iter(Infinite()) 
 >>> next(y) 
 0 
 >>> next(y) 
 2 
 >>> next(y) 
 4 
 >>> next(y) 
 6 
 >>> next(y) 
 8 
 >>> next(y) 
 10 
 >>> 

И эта цепочка может продолжаться вечно. Это показывает, что с бесконечным итератором мы можем иметь бесконечное количество элементов без необходимости хранить их все в памяти.

В следующем разделе мы увидим, как мы можем реализовать механизм выхода из таких бесконечных итераторов.

Остановка итерации

В предыдущем разделе мы увидели, как создать бесконечный итератор в Python. Однако итераторы обычно не предназначены для бесконечных итераций в Python. Всегда удобно реализовать условие завершения.

Мы можем остановить выполнение итератора навсегда с StopIteration оператора StopIteration. Нам нужно только добавить условие завершения в метод __next__() которое вызовет ошибку при достижении указанного количества итераций. Вот пример:

 class StoppingIteration: 
 def __iter__(self): 
 self.x = 1 
 return self 
 
 def __next__(self): 
 if self.x <= 5: 
 y = self.x 
 self.x += 1 
 return y 
 else: 
 raise StopIteration 
 
 classinstance = StoppingIteration() 
 element = iter(classinstance) 
 
 for a in element: 
 print(a) 

Выход

 1 
 2 
 3 
 4 
 5 

Выполнение останавливается после 5 итераций. Это из-за self.x <= 5: добавленного в метод __next__() . Если итератор вызывается после достижения 5, он StopIteration событие StopIteration. Рассмотрим пример, приведенный ниже:

 class StoppingIteration: 
 def __init__(self, max = 0): 
 self.max = max 
 
 def __iter__(self): 
 self.x = 1 
 return self 
 
 def __next__(self): 
 if self.x <= self.max: 
 val = 3 ** self.x 
 self.x += 1 
 return val 
 else: 
 raise StopIteration 

Давайте создадим итератор, а затем переберем его:

 >>> y = StoppingIteration(3) 
 >>> z = iter(y) 
 >>> next(z) 
 3 
 >>> next(z) 
 9 
 >>> next(z) 
 27 
 >>> next(z) 
 Traceback (most recent call last): 
 File "<pyshell#5>", line 1, in <module> 
 next(z) 
 File "C:\Users\admin\iteration.py", line 17, in __next__ 
 raise StopIteration 
 StopIteration 
 >>> 

Условие завершения было реализовано в следующем разделе нашего кода:

 if self.x <= self.max: 
 val = 3 ** self.x 

Мы передали итератору значение 3, что означает, что итератор не должен выполнять итерацию более 27, то есть 3 ^ 3.

Заключение

Итераторы чрезвычайно полезны, особенно если вам нужно перебрать большую последовательность элементов. Итераторы позволяют выполнять итерацию по последовательности элементов по одному без необходимости загружать все элементы в память сразу.

В этой статье мы увидели, как создавать итераторы в Python и как перебирать элементы в итераторе. Мы также увидели, как создать бесконечный итератор и как добавить условие завершения к бесконечному итератору.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus