In any programming language especially python, Iteration simply means to access each item of something one after another generally using a loop. For instance, a list of car names can be printed out one by one using a for loop, like this:
# list of cars cars = ['Hyundai', 'BMW', 'Jaguar', 'Kia', 'MG'] for car in cars: print("Name of car: ", car)
Output:
Name of car: Hyundai Name of car: BMW Name of car: Jaguar Name of car: Kia Name of car: MG
The process shown above was iteration which involved accessing all the items of the list one by one.
An iterable in python programming is referred to as anything that can be looped through or can be iterated over.
For instance, lists, tuples, dictionaries, etc. all are iterable. In simpler words, anything that can appear on the right side of a for-loop: for x in iterable: … is iterable.
One important property of an iterable is that it has an __iter__() method or iter() method and this method specifically allows any iterable to return an iterator object.
Internally the iter() method makes a call to the __iter__() method and returns an iterator object.
An iterator is an object which can be looped through and it maintains its state during the iteration by remembering where it is during an iteration i.e. It has the last memory.
An Iterator in python programming has a __next__() method that returns the next value in the iteration and updates the state to point at the next value.
Iterators also have a method that returns a self-object known as the __iter__ method.
Iterator object can easily be gotten either by passing a predefined or pre-created iterable to the iter() method or by using the __iter__() method on that iterable.
Check out this example:
# list of cars cars = ['Audi', 'BMW', 'Jaguar', 'Kia', 'MG', 'Skoda'] # get iterator object using the iter() method cars_iter = iter(cars) # use the next method to iterate through the list print(next(cars_iter)) # let's do it once more print(next(cars_iter)) # want to see how to use __next__() print(cars_iter.__next__()) # one more time print(cars_iter.__next__()) # lets finish the list print(cars_iter.__next__()) # this will print Skoda which is the last element print(cars_iter.__next__()) # this will give error print(cars_iter.__next__())
Output:
Audi BMW Jaguar Kia MG Skoda Traceback (most recent call last): File "/tmp/sessions/52ed47aa5f103wwe/main.py", line 25, in <module> print(cars_iter.__next__()) StopIteration
In the above example, the iter() method was used, well the __iter__() method can also be used like this:
# we can use __iter__() method too cars_iter_new = cars.__iter__() # print the data print(cars_iter_new.__next__())
Depicting from the example above, the state of the corresponding iterator is incremented and the value that is next to the previous value is returned through the next() or the __next__() method.
Also, there is an exception in the output that won't be unnoticed and the exception is the StopIteration exception which occurs when there are no values left in an iterator to iterate i.e. after the list has ended and to call the next() or __next__() method is called.
Python provides loops like the for loop which internally performs all the steps mentioned above. It minimizes the stress involved in getting the iterator object and then calling the next function again and again.
So whenever a for loop is used like the below sample:
# list of cars cars = ['Audi', 'BMW', 'Jaguar', 'Kia', 'MG', 'Skoda'] for car in cars: print("Name of car: ", car)
The for loop does this internally:
# iterator object is created iter_obj = iter(cars) while True: try: element = next(iter_obj) # perform some operation like print the value except StopIteration: # break out of loop when the list ends break
In python programming, for loop is created to aid the iteration of iterable items using the iterator object as it works internally.
Creating our iterators is not a herculean task as it involves implementing __iter__() and __next__() methods.
An object of the iterator which in our case will be the object of the class itself will be returned when the __iter__() method is used.
And the next element will be returned every time the __next__() method is called thereby raising the StopIteration exception upon reaching the end.
Below is a simple class Counting which will print the counting starting from 1 till the number provided while the class is initiated.
class Counting: def __init__(self, limit): self.limit = limit # implementing the __iter__ method def __iter__(self): self.current = 0 return self # implementing the __next__ method def __next__(self): if self.current < self.limit: self.current += 1 return self.current else: raise StopIteration if __name__=='__main__': # create object of Counting class counting = Counting(10) # use for loop on it for x in counting: print(x)
Output:
1 2 3 4 5 6 7 8 9 10
Lastly, the iter() method can also be called on the object of the Counting class then employ the next() method on the iterator to print the values one by one.