In Python, objects can be broadly classified into one of the two groups, iterable or non-iterable. If an object is capable of returning its member value one by one its iterable; if it is not capable, it is non-iterable. For non-iterable objects, we have to treat the content as a single unit only; however, an iterable object’s content is like a collection of elements that can be individually traversed. Some common examples of iterable objects are lists, tuples, sets, and dictionaries.
student_list=['Ravi','Shivam','Teja','Rohan']
student_tuple=('Ravi','Shivam','Teja','Rohan')
student_set={'Ravi','Shivam','Teja','Rohan'}
student_dict = {'name': 'Ravi', 'branch': 'CSE', 'year': 3 }
Python has a dedicated object called iterators used for iterating over iterable objects. These iterators are implemented using two methods, and , that are commonly known as iterator protocol. The task of is to initialize the method; whereas, is used to perform an iteration over the iterable object.
is used to create the iterator over the iterable object. The iterator created is a value extractor that extracts the successive values from the iterable object to that which it is associated.
itr = iter(student_list)
# <list_iterator object at 0x0000022C0D8C0AF0>
Once the iterator is created, the built-in function next()
is used to obtain the next value from the iterator. This value will start from the first element.
next(itr)
# 'Ravi'
The above code will return the first element from the list, i.e., . Similarly, when we call it again, it will return the next element from the list.
next(itr)
# 'Shivam'
If all the values from an iterator have been returned, a subsequent next()
call raises a StopIteration
exception. Any further attempts to obtain values from the iterator will fail.
In a nutshell we can state that, if we have an iterable object (say ), then an iterator can be obtained over it using iter(a) and that each next()
call over the created iterator will obtain the next value from .
student_list = ['Ravi','Shivam','Teja','Rohan']itr = iter(student_list)print(next(itr))print(next(itr))
Python supports user-defined iterators. To build a user-defined iterator, one needs to implement __iter__()
and __next__()
:
__iter__()
should return the iterator object and initialize if required.__next__()
should return the next item in the defined pattern.Example: Imagine we want to build an iterator that returns the multiple of 5. So, our iterator would start with 5 and each call of next
would return its multiple (10,15,20…):
class FiveMultiple:
def __iter__(self):
self.num = 5
return self
def __next__(self):
val = self.num
self.num += 5
return val
tableiter = iter(FiveMultiple())
print(next(tableiter))
print(next(tableiter))
If the above iterator is called continuously, it will go on through the execution and will not terminate as there is no termination step. Due to this, the above code may also go for an infinite loop. To avoid this, in __next()__
a condition should be specified in __next()__
that, up to that point, only the iterator should run; else, StopIteration
should be called. For this, the above definition of next
should be modified as shown below:
def __next__(self):
if(self.num==100):
val = self.num
self.num += 5
return val
else:
raise StopIteration
class FiveMultiple:def __iter__(self):self.num = 5return selfdef __next__(self):val = self.numself.num += 5return valtableiter = iter(FiveMultiple())print(next(tableiter))print(next(tableiter))