An iterator is an object that allows you to iterate through a collection one item at a time.
Python provides a simple and powerful way to create and use iterators using the iter() and next() functions.
next() is called.
An iterator is an object that implements the iterator protocol. It provides two important methods:
__iter__()__next__()
The __iter__() method returns the iterator object itself, while __next__() returns the next value.
An iterable is an object that can provide an iterator.
Examples of iterables include:
An iterator is the object that produces values one at a time.
The iter() function creates an iterator from an iterable object.
numbers = [10, 20, 30]
iterator = iter(numbers)
print(iterator)
The variable iterator now refers to an iterator for the list.
The next() function retrieves the next item from an iterator.
numbers = [10, 20, 30]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
10 20 30
An iterator keeps track of where it is in the sequence.
numbers = [10, 20, 30, 40]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
10 20 30
Each call to next() moves the iterator forward.
When there are no more items, calling next() raises a StopIteration exception.
numbers = [10, 20]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
10 20 StopIteration
The next() function can receive a second argument that is returned when the iterator is exhausted.
numbers = [10, 20]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator, "No more items"))
10 20 No more items
A for loop can automatically use an iterable's iterator.
numbers = [10, 20, 30, 40]
for number in numbers:
print(number)
10 20 30 40
The for loop handles the iterator protocol and StopIteration automatically.
We can create our own iterator by defining __iter__() and __next__().
class Count:
def __init__(self, limit):
self.limit = limit
self.number = 1
def __iter__(self):
return self
def __next__(self):
if self.number <= self.limit:
value = self.number
self.number += 1
return value
raise StopIteration
numbers = Count(5)
print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))
1 2 3 4 5
The __iter__() method returns an iterator object.
class Numbers:
def __iter__(self):
return self
For an iterator object, returning self from __iter__() is the normal pattern.
The __next__() method returns the next item from an iterator.
class Numbers:
def __init__(self):
self.number = 1
def __iter__(self):
return self
def __next__(self):
value = self.number
self.number += 1
return value
numbers = Numbers()
print(next(numbers))
print(next(numbers))
print(next(numbers))
1 2 3
A custom iterator can stop after reaching a particular limit.
class Numbers:
def __init__(self, limit):
self.limit = limit
self.number = 1
def __iter__(self):
return self
def __next__(self):
if self.number <= self.limit:
value = self.number
self.number += 1
return value
raise StopIteration
numbers = Numbers(3)
for number in numbers:
print(number)
1 2 3
An iterator needs a way to tell Python that there are no more values.
The standard way is to raise StopIteration.
raise StopIteration
A for loop catches this internally and stops the loop.
Strings are iterable objects.
text = "Python"
iterator = iter(text)
print(next(iterator))
print(next(iterator))
print(next(iterator))
P y t
numbers = (10, 20, 30)
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
10 20 30
Iterating directly over a dictionary produces its keys.
student = {
"name": "Rahul",
"age": 20,
"course": "Python"
}
iterator = iter(student)
print(next(iterator))
print(next(iterator))
print(next(iterator))
name age course
Sets are iterable, but their iteration order is not something you should rely on.
numbers = {10, 20, 30}
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
The values are returned one at a time, but the order is not guaranteed by the set data structure.
Calling iter() on an iterator returns the iterator itself.
numbers = [10, 20, 30]
iterator = iter(numbers)
same_iterator = iter(iterator)
print(iterator is same_iterator)
True
The iterator protocol consists mainly of two methods:
| Method | Purpose |
|---|---|
__iter__() |
Returns an iterator object. |
__next__() |
Returns the next item. |
When no more items are available, __next__() should raise StopIteration.
A for loop works with an iterable by obtaining an iterator and repeatedly requesting the next value.
numbers = [1, 2, 3]
for number in numbers:
print(number)
Conceptually, Python performs the iterator operations behind the scenes and stops when StopIteration occurs.
| Iterable | Iterator |
|---|---|
| Can provide an iterator. | Produces values one at a time. |
| Examples include list, tuple and string. | Created using iter() or by implementing the iterator protocol. |
| Usually can be iterated over again by obtaining a new iterator. | Maintains its current position. |
Imagine a book containing many pages. Instead of opening every page at the same time, you can read one page at a time.
An iterator works in a similar way: it provides the next item only when requested.
class EvenNumbers:
def __init__(self, limit):
self.limit = limit
self.number = 2
def __iter__(self):
return self
def __next__(self):
if self.number <= self.limit:
value = self.number
self.number += 2
return value
raise StopIteration
numbers = EvenNumbers(10)
for number in numbers:
print(number)
2 4 6 8 10
iter() is used to obtain an iterator from an iterable.next() returns the next value.__iter__() returns an iterator.__next__() returns the next item.StopIteration indicates that there are no more items.for loop automatically handles iteration.Question: Which function is used to get the next item from an iterator?