1. Introduction
An iterator is an object that produces a sequence of values one at a time, remembering its position between calls. Iterators are the mechanism that powers Python's for loops: whenever you write 'for item in collection', Python is using an iterator behind the scenes to fetch each item.
Cricket analogy: Virat Kohli facing deliveries one ball at a time in an over, remembering the score and strike rate between balls, is like an iterator yielding one value per call and tracking where it left off.
Any object that implements the iterator protocol, __iter__() and __next__(), can be used anywhere Python expects an iterable, including for loops, list(), and the built-in next() function.
Cricket analogy: Any batter who follows the rules of facing a legal delivery -- bat, stance, guard -- can play in any format, just as any object implementing __iter__ and __next__ can be used in for loops, list(), or next().
2. Syntax
class MyIterator:
def __iter__(self):
return self # an iterator must return itself
def __next__(self):
# return the next value, or raise StopIteration when done
raise StopIteration
# Using iterators manually
it = iter(some_iterable) # calls __iter__
value = next(it) # calls __next__
# for loops use this protocol automatically
for value in some_iterable:
print(value)3. Explanation
An iterable is any object with an __iter__() method that returns an iterator; an iterator is an object with both __iter__() (usually returning itself) and __next__(), which returns the next value each time it is called. When there are no more values, __next__() must raise StopIteration to signal the end.
Cricket analogy: A full scorecard (iterable) can produce a ball-by-ball commentator (iterator) who reads out each delivery and declares 'innings closed' -- StopIteration -- once the last wicket falls or overs end.
The built-in iter() function calls an object's __iter__() method, and next() calls __next__(). A for loop is essentially syntactic sugar: it calls iter() once on the iterable, then repeatedly calls next() on the resulting iterator, catching StopIteration automatically to end the loop.
Cricket analogy: Calling 'iter()' is like the umpire signaling 'start play,' and each 'next()' call is like calling for the next ball; the for loop is the entire over auto-managed until the umpire calls 'over' -- catching StopIteration.
The iterator protocol requires __iter__() and __next__(). Once __next__() raises StopIteration, the iterator is considered exhausted; calling next() on it again typically continues to raise StopIteration rather than restarting the sequence.
4. Example
class CountUpTo:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
self.current += 1
return self.current
counter = CountUpTo(3)
it = iter(counter)
print(next(it))
print(next(it))
print(next(it))
for num in CountUpTo(4):
print('loop:', num)5. Output
1
2
3
loop: 1
loop: 2
loop: 3
loop: 46. Key Takeaways
- An iterable has __iter__(); an iterator has both __iter__() and __next__().
- __next__() must raise StopIteration when there are no more items to return.
- for loops internally call iter() once and then next() repeatedly, catching StopIteration to stop.
- Once exhausted, an iterator generally cannot be restarted; a new iterator must be created.
- iter() and next() are the built-in functions that drive the iterator protocol manually.
Practice what you learned
1. What exception must __next__() raise to signal the end of iteration?
2. What two special methods make up the iterator protocol?
3. What does a for loop do internally with an iterable?
4. What does the built-in function next() do?
5. What generally happens if you call next() on an iterator after it has already raised StopIteration once?
Was this page helpful?
You May Also Like
Generators in Python
Learn how to write generator functions with yield to produce lazy, memory-efficient sequences of values in Python.
for Loop in Python
Understand how Python's for loop iterates over sequences and iterables like lists, strings, and ranges.
List Comprehension in Python
A concise Python syntax for building lists from iterables in a single expression, including conditionals and the memory-difference vs generator expressions.
Magic (Dunder) Methods in Python
How Python's double-underscore methods let your classes plug into built-in syntax like print(), ==, len(), and hashing.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics