In Python, iterators are objects that allow you to traverse through all the elements of a collection (such as lists, tuples, or dictionaries) one at a time. Iterators are a key part of Python’s data-handling capabilities, enabling efficient processing of data structures or even creating custom iteration logic.
Key Concepts of Iterators
Iterator Protocol: An object is considered an iterator if it implements two special methods:
__iter__()
– Returns the iterator object itself and is used for initialization.__next__()
– Returns the next item in the sequence and raisesStopIteration
when there are no more items.
Iterable vs. Iterator:
Iterable: An object that can return an iterator, typically using the __iter__()
method (e.g., lists, tuples, dictionaries).
Iterator: An object that keeps track of its current state and knows how to fetch the next element in the sequence. It is created by calling iter()
on an iterable.
Example:
Consider a list, which is an iterable. You can get an iterator from it using the iter()
function:
# List (Iterable)
numbers = [1, 2, 3]
# Getting an Iterator
iterator = iter(numbers)
# Using the Iterator
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
If you call next(iterator)
after the last item, it will raise a StopIteration
exception, signaling that the iteration is complete.
Creating a Custom Iterator
To create a custom iterator, you define a class with __iter__()
and __next__()
methods.
Here’s an example of a custom iterator that generates a sequence of numbers up to a specified limit:
class MyIterator:
def __init__(self, max_value):
self.max_value = max_value
self.current = 0
def __iter__(self):
return self # An iterator returns itself
def __next__(self):
if self.current < self.max_value:
result = self.current
self.current += 1
return result
else:
raise StopIteration
# Using the custom iterator
iterator = MyIterator(5)
for number in iterator:
print(number) # Output: 0 1 2 3 4
In this example:
The __iter__()
method returns the iterator instance itself.
The __next__()
method increments the current
attribute until it reaches max_value
, after which it raises StopIteration
.
Difference between Iterators vs Generators
While iterators and generators both allow you to iterate through data, they are slightly different:
Iterators require you to implement __iter__()
and __next__()
.
Generators simplify iteration by using the yield
keyword, automatically managing the state without needing to write __iter__()
and __next__()
methods.