Mastering Artificial Intelligence

Python Iterators

Iterators, this name might be new for most of us, but What if I tell you that you have already used this within for loops, comprehensions etc. So, in this blog, let’s see what are iterators, how they work and how we can build our own iterator.

What is an iterator and how it works?

To understand this, we first need to know what is an iterable

Iterable: It is anything that you are able to loop over like lists, tuples, strings etc.

Iterator: It is the object that does the actual iterating.

So, in order to iterate, you must first convert an iterable into an iterator. This is done by using built-in iter() function.

Python

1

2

3

4

>>>my_list=[1,2,3,4]

>>>iter_obj=iter(my_list)

>>>iter_obj

<list_iterator objectat0x000000E7431745F8>

To get the next element, use built-in next() function on that iterator. next() function raises a StopIteration exception when there are no more elements in that iterator.

Python

1

2

3

4

>>>next(iter_obj)

1

>>>next(iter_obj)

2

Note: If we directly apply next() on iterable like lists etc. it will give a typeerror as

Python

1

2

3

4

5

>>>next(my_list)

Traceback(most recent call last):

File"<pyshell#5>",line1,in<module>

next(my_list)

TypeError:'list'objectisnotan iterator

Thus, __iter__() and __ next__() (called the iterator protocol)are the two special methods implemented by the iterator.

Pros: Iterators are lazy, meaning, they don’t determine what their next item is until you ask them for it. This saves memory, time and can work with infinite sequences.

Building our own iterator:

To build an iterator, we only need the methods __iter__() and __next__(). Below, we show an example that will give us the next Fibonacci term in each iteration.

Building your own iterator in Python

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

classFib:

def__init__(self,max=0):

self.max=max

self.a=0

self.b=1

self.n=0

def__iter__(self):

returnself

def__next__(self):

ifself.n<=self.max:

result=self.a+self.b

self.a,self.b=self.b,result

self.n+=1

returnresult

else:

raiseStopIteration

Now we can create an iterator and iterate through it as follows.

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

>>>a=Fib(3)

>>>next(a)

1

>>>next(a)

2

>>>next(a)

3

>>>next(a)

5

>>>next(a)

Traceback(most recent call last):

File"<pyshell#6>",line1,in<module>

next(a)

File"C:\New folder\pp.py",line19,in__next__

raiseStopIteration

StopIteration

Here, I haven’t called the iter() method because it returns the object itself. You may call this, as this will not affect anything.