Iterators are the objects in Python which contain any countable number of values or that which can return one value at a time. The iterators can be iterated, in other words all their values can be explored. Iterators are the ones which implement the iterator class protocol, which consists of these two methods _ _next_ _( ) and the _ _iter_ _ method. An object can be called iterable if we get an iterator from it. Most built-in containers of the Python are iterable.
Here is the index, listing the topics we will learn in this article.
Here are few examples of the iterators in Python.
mytuple = ("Earth", "Neptune", "Mars") myit = iter(mytuple) print(next(myit)) print(next(myit)) print(next(myit))
Here, we can see that we have used the ‘iter’ method. Since there are three values in the ‘mytuple’, because iterators will give us one value at a time as shown in the result.
Earth Neptune Mars
mystr = "gamers" myit = iter(mystr) print(next(myit)) print(next(myit)) print(next(myit)) print(next(myit)) print(next(myit)) print(next(myit))
In this code, we will extract the letters of the word ‘gamers’.
g a m e r s
The iteration protocol
The iteration protocol is the systematic way in which iterables work in python. Here are the statements which define what iteration protocols are in Python.
Conversely, these statements can be described as anything that passes through the iter without raising any error. For the iterators, anything that can be passed through the next without any error is defined as an iterator, except StopIteration or if it returns it when passed through the iter is also defined as the iterator. These are protocols or rules, of how the iteration project is done.
Uses of Iterators in python
Iterators are used for the variety of functions in Python. With the use of iterators one can create iterables. These iterables only function in real time that means they only work when we require the next item.
With the use of these iterators, we can create infinitely large iterables. Conservative resources can also be created if we want to save CPU processing time and memory.
Python generators provide us with easy options to create python iterators. This is done by the use of the function in spite of using the return statement. This is done with python yield statement. Now, we will explore the question “what is generator in python?”.
Here is an example to make it clear:
def primenumbers_lessthan5(): <span style="white-space:pre"> </span>yield "2" <span style="white-space:pre"> </span>yield "3" for i in primenumbers_lessthan5(): print(i)
We are using the python yield statement to extract prime numbers less than 5. The result of this code will be:
We have got the result as we wanted using the yield statement. The yield statement can also be used in the ‘for’ loop in same way as we make use of iterators in Python.
Here is an example for this:
def my_program(): <span style="white-space:pre"> </span>yield 'Python' <span style="white-space:pre"> </span>yield 'Ruby' <span style="white-space:pre"> </span>yield 'C' for char in my_program(): <span style="white-space:pre"> </span>print(char)
As we can see in the above example we have used ‘for’ statement along with the ‘for’ loop. The result of the code will be as follows.
Python Ruby C
Python Generator can also be used to generate infinite values.
Python Generator expressions are similar to list comprehensions in the appearance. The difference is that instead of the list, python generator expressions return a generator.
They are helpful in saving memory. It will become clear with this example:
k = sum(x*x*x for x in range(1,5)) print (k)
As we can see that the as per the syntax of the python generator expression, we have to ensure that we use parentheses inside on the either side. Here is the result:
Since the Python generator can also be looped upon, the generators are also iterators.
Generators are sometimes known as generator functions or resumable functions. These functions return a generator instead of the generator iterator. The generator is defined like a normal function however whenever it requires to generate a value. It uses ‘yield’ keyword for that instead of using the return.
They allow us to declare if any generator functions behave as an iterator.
Python Generators are very useful to programmers in case they have to deal with a large amount of data. We can iterate a large amount of numbers and even infinite datasets without having to store them in the memory. Here we will look at the endless generator examples:
def fibonacci(): """Generates an infinite sequence of Fibonacci numbers on demand""" a, b = 0, 1 while True: <span style="white-space:pre"> </span>yield a <span style="white-space:pre"> </span>a, b = b, a + b f = fibonacci() counter = 0 for x in f: print(x, " ", end="") counter += 1 print()
In this code, you can see that we are generating a Fibonacci sequence. Since there is no counter break, we will get an infinite result and ultimately result in the time limit exceeded. This will not be convenient to display it here. Hence we will display the same code but this time with a break.
def fibonacci(): """Generates an infinite sequence of Fibonacci numbers on demand""" a, b = 0, 1 while True: <span style="white-space:pre"> </span>yield a <span style="white-space:pre"> </span>a, b = b, a + b f = fibonacci() counter = 0 for x in f: print(x, " ", end="") counter += 1 if (counter > 10): <span style="white-space:pre"> </span>break print()
0 1 1 2 3 5 8 13 21 34 55
We require using the next function for starting the python3 iterator and then we can advance it to python yield statement. We will use a decorator generator code now.
def infinite_looper(objects): count = -1 message = yield None while True: <span style="white-space:pre"> </span>count += 1 <span style="white-space:pre"> </span>if message != None: <span style="white-space:pre"> </span>count = 0 if message < 0 else message <span style="white-space:pre"> </span>if count >= len(objects): <span style="white-space:pre"> </span>count = 0 <span style="white-space:pre"> </span>message = yield objects[count] x = infinite_looper("batman") print(next(x)) print(x.send(4)) print(next(x)) print(next(x)) print(x.send(5)) print(next(x))
The result of the decorator code will be as follows.
b a n b n b
The itertools modules provide a lot of tools that we can use for a variety of activities. Some of those functions have been described below:
This tool is used if we need to chain multiple iterators together.
from itertools import chain for i in chain(['x', 'y', 'z'], ['a', 'b', 'c']): print (i)
x y z a b c
This tool returns an iterator combines the elements of iterators into tuples.
from itertools import *
for x, y in zip(["a", "b", "c"], [1, 2, 3]):
print (x, y)
from itertools import * <span style="white-space:pre"> </span> print ('Stop at 5:') for i in islice(count(), 5): print (i) print ('Start at 5, Stop at 10:') for i in islice(count(), 5, 10): print (i) print ('By tens to 100:') for i in islice(count(), 0, 100, 10): print (i)
Stop at 5:
Start at 5, Stop at 10:
By tens to 100:
tee tool returns iterators which are independent, on the basis of the single
from itertools import * r = islice(count(), 4) i1, i2 = tee(r) for i in i1: print ('i1:', i) for i in i2: print ('i2:', i)
i1: 0 i1: 1 i1: 2 i1: 3 i2: 0 i2: 1 i2: 2 i2: 3
Python Iterators, generators, and the ‘for’ loop
The ‘for’ loop can be used with iterators and generators. The ‘for’ statement is used while looping, as looping is done with the use of iterators in Python along with generators, the ‘for’ loop is important to use. There are many objects that can be used with ‘for’ loop. All of those objects are called iterable objects.
Difference between Python Generators and Iterators
Although it might seem that the difference between Python iterators and generators is a little confusing, the issue can be resolved with a careful understanding. Here are the differences between Python generators and iterators. Please take a proper look at them to avoid confusion.
|Large number of functions can be used to create Python Generators.||Only iter( ) and next( ) can be used to create Python iterators.|
|Generators in Python use the keyword ‘yield’.||Iterators in Python are not required to do so.|
|Generators in Python save the local state of the variable whenever ‘yield’ causes them to stop.||Iterators do not use local variable. They only iterate on iterables.|
|Generators in python do not require any iterator class.||It is necessary to have iterator class in Python.|
|Generators provide facility of fast coding and easy writing.||While the process is a little longer and complex in case of the iterators.|
|Generators are not memory efficient.||Iterators are memory efficient|
|Generators in python return a generator.||Iterators return an iterator object.|
Free Demo for Corporate & Online Trainings.