
1. Итератор языка Python
В этой статье, посвященной итераторам и их применению в языке Python, мы также рассмотрим создание своих собственных методов __iter__() и __next__(), соберем свой собственный итератор, рассмотрим всю пользу итераторов и закрепим наши знания на примерах.
Итак, начинаем наш туториал по итераторам в Python.
2. Кто такие эти ваши итераторы?
Итератор в языке программирования Python — это объект, который вы можете перебирать. То есть он возвращает по одному объекту за раз. Итератор Python, неявно реализован в таких конструкциях, как циклы for, comprehension’ах и генераторах Python. Функции iter() и next() как раз и образуют протокол итератора.
Если мы можем получить итератор от объекта в Python, значит он итерабельный. Например, списки Python, кортежи и строки.
3. А как создать итератор?
Чтобы собрать итератор python3, мы используем функции iter() и next(). Давайте начнем с iter(), чтобы создать итератор.
Сначала мы создаем список, который содержит все четные числа от 2 до 10.
evens=[2,4,6,8,10]
Затем мы применяем функцию iter() к этому списку Python, чтобы создать объект итератора. Мы храним его в переменной evenIterator.
evenIterator=iter(evens) evenIterator <list_iterator object at 0x05E35410>
Помните, итератор можно получить не только для списка, кортежи и даже множества отлично подойдут.
iter((1,3,2)) <tuple_iterator object at 0x05E35550>
Теперь, чтобы получить доступ к первому элементу, мы применяем функцию next() к объекту итератора Python.
next(evenIterator) 2 next(evenIterator) 4 next(evenIterator) 6 next(evenIterator) 8 next(evenIterator) 10
Мы достигли конца списка. Когда мы вызываем его еще раз, мы провоцируем ошибку StopIteration (исключение). Интерпретатор сразу же выбрасывает его.
next(evenIterator) Traceback (most recent call last): File “<pyshell#442>”, line 1, in <module> next(evenIterator) StopIteration
С методом iter() разобрались, посмотрим на __next__()
Итак, вы можете пройтись по итератору в Python, используя метод __next __() вместо next(). (Ну, мало ли…)
nums=[1,2,3] numIter=iter(nums) numIter.__next__() 1 >>> next(numIter) 2 >>> numIter.__next__() 3 >>> numIter.__next__() Traceback (most recent call last): File “<pyshell#448>”, line 1, in <module> numIter.__next__() StopIteration
Мы можем увидеть этот метод с помощью функции dir().
>>> dir(numIter) [‘__class__’, ‘__delattr__’, ‘__dir__’, ‘__doc__’, ‘__eq__’, ‘__format__’, ‘__ge__’, ‘__getattribute__’, ‘__gt__’, ‘__hash__’, ‘__init__’, ‘__init_subclass__’, ‘__iter__’, ‘__le__’, ‘__length_hint__’, ‘__lt__’, ‘__ne__’, ‘__new__’, ‘__next__’, ‘__reduce__’, ‘__reduce_ex__’, ‘__repr__’, ‘__setattr__’, ‘__setstate__’, ‘__sizeof__’, ‘__str__’, ‘__subclasshook__’]
4. Цикл for для итераторов Python
Вы также можете использовать цикл for в Python для итерации по какому-нибудь итерируемому объекту, например, по списку Python или по кортежу.
for i in 'Python': print(i) P y t h o n
Но как это на самом деле реализовано? Давайте взглянем.
iter_obj=iter('Python') while True: try: i=next(iter_obj) print(i) except StopIteration break P y t h o n
Это была простая версия. Вот как на самом деле реализован вышеприведенный цикл for.
5. Наконец создаем свой собственный итератор
Теперь вы знаете, как использовать итератор с функциями iter() и next(). Но мы не остановимся на этом. Теперь мы начнем с самого нуля.
Мы реализуем следующий класс для создания итератора в Python для квадратов чисел от 1 до максимального указанного.
class PowTwo: def __init__(self, max=0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: result = 2 ** self.n self.n += 1 return result else: raise StopIteration
Здесь __init __() принимает значение max. Затем мы создаем объект «a» класса PowTwo с аргументом 4. Затем мы создаем итератор, используя iter(). Далее мы используем функцию next(), чтобы получать элементы один за другим.
a=PowTwo(4) i=iter(a) next(i) 1 >>> next(i) 2 >>> next(i) 4 >>> next(i) 8 >>> next(i) 16 >>> next(i) Traceback (most recent call last): File “<pyshell#484>”, line 1, in <module> next(i) File “<pyshell#476>”, line 13, in __next__ raise StopIteration StopIteration
В качестве альтернативы вы можете использовать методы __iter __() и __next __() для этого объекта.
j=a.__iter__() j.__next__() 1 >>> j.__next__() 2 >>> j.__next__() 4 >>> j.__next__() 8 >>> j.__next__() 16 >>> j.__next__() Traceback (most recent call last): File “<pyshell#491>”, line 1, in <module> j.__next__() File “<pyshell#476>”, line 13, in __next__ raise StopIteration StopIteration
Функция iter() вызывает метод __iter __() внутри себя.
6. Бесконечный итератор
В Python действительно возможно создать итератор, который никогда не исчерпывается. Функция iter() может принимать другой аргумент, называемый «страж». Этот страж является точкой выхода и работает следующим образом: как только значение, возвращаемое итератором равно значению стража, итератор заканчивается.
Мы знаем, что функция int() без параметра внутри возвращает 0.
>>> int()
Теперь мы вызываем iter() с двумя аргументами — int и 1.
>>> a=iter(int,1)
Этот итератор Python никогда не исчерпает себя, он бесконечен. Это потому, что 0 никогда не равен 1. Серьезно, никогда.
>>> next(a) >>> next(a) >>> next(a) >>> next(a) >>> next(a)
И так далее.
Чтобы создать бесконечный итератор Python с использованием класса, рассмотрим следующий пример.
class Even: def __iter__(self): self.num=2 return self def __next__(self): num=self.num self.num+=2 return num >>> e=Even() >>> i=iter(e) >>> next(i) 2 >>> next(i) 4 >>> next(i) 6 >>> next(i) 8
Здесь Python перебирает четные числа, начинающиеся с 2 и никогда не заканчивающиеся. Таким образом, вы должны быть осторожны и обеспечить завершающее условие (точку выхода).
7. Преимущества итераторов языка Python
Итератор в python экономит ресурсы. Чтобы получить все элементы, в памяти одновременно хранится только один элемент. В отличие от итератора, список должен хранить все значения одновременно.
8. Делаем выводы
В этой статье мы узнали об итераторах Python. Разве они не веселые и супер удобные? Итератор использует всего две функции — iter() и next(). Тем не менее, мы можем сделать наш собственный итератор в Python при помощи класса. Наконец, мы рассмотрели также бесконечные итераторы.
Кроме того, если у вас есть какие-либо вопросы/сомнения, не стесняйтесь задавать их в поле для комментариев.