We are going to discuss about the Python Iterator in this article. Iterator is an object with state and it remembers where it is and when it is iterating. It returns the single object. It uses the Iter() and next() methods. This is used to form the loops, comprehensions, and python generators.
Convert any sequence to iterator using the following syntax:
To access the next element, the next() function is used. Any object in Python which supports the previous two methods is called iterator. To check this, run the inbuilt method dir() on object.
Example: print(dir(list))
Here, the list is not an iterator since it is does not have the “ __next__” method.
If we try to access the next elements, we get the exception as follows:
To convert it as iterator, pass the list to the iter method as shown in the following. After that, we see the “__next__” method.
Difference Between Iterator and Iterable
Iterable means we can loop over the values like list, tuple, string etc. All objects have an iter() method which is used to get an iterator. We will see some examples to understand it better:
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | nums = [1,2,3,4,5] numsIterator = iter(nums) #same as numsIterator = nums.__iter__() # internally it will call __iter__ dunder method print(next(numsIterator)) # Access 1st element print(next(numsIterator)) # Access 2nd element print(next(numsIterator)) # Access 3rd element and so on... print(next(numsIterator)) print(next(numsIterator)) print(next(numsIterator)) |
When we reach the end of the list, it raises a StopIteration error.
Note: Anything that starts with the double underscore and ends with the double underscore in Python is called dunder method.
Use Case of Iterators
- The for loop uses iterators in the background.
Example 1:
We print each character using the for loop.
1 2 3 4 5 | s = "Good morning" for char in s: print(char) |
Example 2:
We print the same string using the iterators.
1 2 3 4 5 6 7 8 9 10 11 | s = "Good morning" word = iter(s) while True: try: item = next(word) print(item) except StopIteration: break |
- Another use case of the iterator is adding the next() and iter() methods to our class and make it as iterable.
Example 3:
To build our own range function, range function gives the range of values from start to end (exclusive).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class myRange: def __init__(self, start, stop): self.val = start self.stop = stop def __iter__(self): return self def __next__(self): if self.val >= self.stop: raise StopIteration current = self.val self.val += 1 return current nums = myRange(1,5) print(next(nums)) print(next(nums)) print(next(nums)) print(next(nums)) print(next(nums)) |
- Another use case of the iterator is Python generators. Generators are normal method which yield the value as output and it remembers the state when it is called next time. Generators are iterators as well but the dunder iter() and next() methods are created automatically.
We write the previous range function using the generator.
Example 4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def my_range(start, end): current = start while current < end: yield current current +=1 nums = my_range(1,5) print(next(nums)) print(next(nums)) print(next(nums)) print(next(nums)) |
Or we can call the following which produces the same output as the previous example.
1 2 3 | for num in nums: print(num) |
Conclusion
The iterator needs not to end as long as the value is there; it keeps us get the value. It fetches one value at a time. It is really useful when writing the memory efficient programs where we have some many values that we can’t put in memory if we put them in a list or tuple. We can save the resource with this.