Iterators in Python
An iterator is an object that contains a countable number of values and can be iterated upon, meaning that you can traverse through all the values. In Python, an iterator is an object that implements the iterator protocol, which consists of the methods __iter__()
and __next__()
.
Creating an Iterator
You can create an iterator by defining a class that implements the __iter__()
and __next__()
methods. The __iter__()
method initializes the iterator, and the __next__()
method returns the next value in the sequence.
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter)) # Output: 1
print(next(myiter)) # Output: 2
print(next(myiter)) # Output: 3
Using Iterators with Loops
Iterators are often used in loops, such as for loops, to traverse through the elements. This allows for efficient iteration over sequences without the need to store the entire sequence in memory.
for x in myiter:
print(x)
if x > 5:
break
# Output:
# 4
# 5
# 6
In this example, the iterator continues to produce values until the loop is explicitly stopped with a break
statement.
Iterator vs Iterable
It’s important to distinguish between an iterator and an iterable:
- Iterable: An object that can return an iterator. Examples include lists, tuples, strings, and dictionaries. Iterables implement the
__iter__()
method, which returns an iterator. - Iterator: An object that represents a stream of data. It implements the
__next__()
method, which returns the next element of the stream.
All iterators are iterables, but not all iterables are iterators. To get an iterator from an iterable, you use the iter()
function.
Stopping Iteration
An iterator raises a StopIteration
exception to signal that there are no further items produced by the iterator. This is usually handled automatically within loops but can also be managed manually when using the next()
function.
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 5:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
# Output:
# 1
# 2
# 3
# 4
# 5
In this example, the iterator stops when the value exceeds 5, raising a StopIteration
exception to terminate the loop.
Custom Iterators
Creating custom iterators allows for more complex iteration logic. You can customize how the iteration progresses, what values are returned, and when the iteration stops.
class Countdown:
def __init__(self, start):
self.start = start
def __iter__(self):
self.n = self.start
return self
def __next__(self):
if self.n > 0:
x = self.n
self.n -= 1
return x
else:
raise StopIteration
countdown = Countdown(5)
for num in countdown:
print(num)
# Output:
# 5
# 4
# 3
# 2
# 1
This custom iterator counts down from the given start value and stops when it reaches zero.
Understanding iterators is crucial for working with sequences in Python, especially when dealing with custom data structures or when you need to efficiently process large datasets.
Import Links
Here are some useful import links for further reading: