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:
|Implemented using a function.||Implemented using a class.|
||Does not use the
|Usage results in a concise code.||Usage results in a relatively less concise code.|
|All the local variables before the
||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 number def upto(n): for i in range(n+1): # The yield statement is what makes a function # a generator yield i for number in upto(5): print(number)
__iter__() method returns the iterator object. This is required to allow an iterator to be used with 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 0 def __init__(self, max = 0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): # The next method will throw an # exception when the termination condition is reached. if self.n > self.max: raise StopIteration else: result = self.n self.n += 1 return result for number in UpTo(5): print(number)
View all Courses