An iterator in Python serves as a holder for objects so that they can be iterated over; a generator facilitates the creation of a custom iterator.
Apart from the obvious syntactic differences, the following are some noteworthy differences:
Generator | Iterator |
---|---|
Implemented using a function. | Implemented using a class. |
Uses the yield keyword. |
Does not use the yield keyword. |
Usage results in a concise code. | Usage results in a relatively less concise code. |
All the local variables before the yield statements are stored. |
No local variables are used. |
Let’s create a generator and an iterator to generate all the non-negative numbers up to the specified positive number.
Remember that a return statement terminates the execution of a function entirely, whereas, the yield
statement saves the function state and resumes its execution, from this point, upon subsequent calls.
# Function to generate all the non-negative numbers# up to the given non-negative numberdef upto(n):for i in range(n+1):# The yield statement is what makes a function# a generatoryield ifor number in upto(5):print(number)
The __iter__()
method returns the iterator object. This is required to allow an iterator to be used with the for
and in
statements.
The __next__()
method returns the next element in the sequence. In the case of a finite iterator, once it reaches the end (defined by the termination condition), all of the subsequent calls to this method should should raise an exception.
# Function to generate all the non-negative numbers# up to the given non-negative number.class UpTo:# giving the parameter a default value of 0def __init__(self, max = 0):self.max = maxdef __iter__(self):self.n = 0return selfdef __next__(self):# The next method will throw an# exception when the termination condition is reached.if self.n > self.max:raise StopIterationelse:result = self.nself.n += 1return resultfor number in UpTo(5):print(number)