Python next Function: How to Retrieve Items from Iterators in CPython
The Python next() built‑in function retrieves the next item from an iterator by calling its __next__ method, optionally returning a default value instead of raising StopIteration when the iterator is exhausted.
The next() function is a fundamental component of Python's iteration protocol, implemented in the CPython source repository (python/cpython). According to the C source, this built‑in serves as the bridge between Python-level code and the low-level C iterator machinery, ensuring fast, uniform element retrieval across all iterator types.
How the Python next Function Works Internally
The C implementation resides in Python/bltinmodule.c as the C function builtin_next. This function is registered with the METH_FASTCALL calling convention, allowing CPython to pass arguments as a C array for maximum performance.
Argument Validation and Fast‑Call Handling
builtin_next expects one required argument—the iterator—and one optional default value. Using the METH_FASTCALL protocol, arguments skip Python tuple packing and arrive directly as a C array, reducing function call overhead significantly.
The Core Iteration Mechanism
Once validated, execution delegates to PyIter_Next (defined in Objects/iterator.c). This helper invokes the iterator's tp_iternext slot, which corresponds exactly to the Python-level __next__ method. By routing through this slot, next() guarantees consistent behavior whether iterating over lists, generators, or custom objects.
StopIteration and Default Value Handling
When PyIter_Next returns NULL, signifying the iterator is exhausted, the logic checks for a user‑provided default. If present, builtin_next returns that default; otherwise, it raises StopIteration (defined in Objects/exception.c). This implements the contract documented in the next_doc docstring: "Return the next item from the iterator. If default is given and the iterator is exhausted, return default instead of raising StopIteration."
Python next Function Syntax and Parameters
The function signature follows standard iterator protocol conventions:
next(iterator, default=None)
- iterator: Any object implementing the iterator protocol (must provide a
__next__method). - default (optional): Value returned when iteration completes instead of raising
StopIteration.
Practical Code Examples Using next()
Basic Iteration with next()
Instantiate any iterable with iter(), then advance manually:
it = iter([10, 20, 30])
print(next(it)) # → 10
print(next(it)) # → 20
Providing a Default Value to Avoid Exceptions
Supply a default to handle exhaustion gracefully without try/except blocks:
it = iter([10, 20, 30])
print(next(it, None)) # → 10
print(next(it, None)) # → 20
print(next(it, None)) # → 30
print(next(it, None)) # → None (iterator exhausted, no StopIteration raised)
Custom Iterator Implementation
When implementing custom iterators, raising StopIteration signals exhaustion to next():
class Counter:
def __init__(self, start=0):
self.n = start
def __iter__(self):
return self
def __next__(self):
if self.n > 5:
raise StopIteration
val = self.n
self.n += 1
return val
c = Counter()
while True:
val = next(c, 'done')
if val == 'done':
break
print(val) # Outputs: 0 1 2 3 4 5
Summary
- The
next()function retrieves items by calling the__next__method through the C-leveltp_iternextslot. - Implementation lives in
Python/bltinmodule.casbuiltin_next, optimized withMETH_FASTCALL. PyIter_NextinObjects/iterator.chandles the generic iterator protocol invocation.- The optional default parameter prevents
StopIterationexceptions, returning the specified value when iterators are exhausted.
Frequently Asked Questions
What is the difference between next() and calling iterator.__next__() directly?
next(iterator) is the idiomatic approach that accepts an optional default value, while iterator.__next__() is the underlying method that always raises StopIteration when exhausted. The built‑in next() function provides a cleaner interface and additional safety via the default parameter.
Where is the next() function implemented in the CPython source code?
The implementation resides in Python/bltinmodule.c as the builtin_next C function. This function utilizes PyIter_Next from Objects/iterator.c to invoke the iterator's tp_iternext slot, which maps to Python's __next__ method.
Why does the next() function have a default parameter?
The default parameter allows developers to handle empty or exhausted iterators without wrapping calls in try/except blocks. When PyIter_Next returns NULL (indicating exhaustion), builtin_next returns the provided default instead of raising StopIteration, enabling cleaner control flow in loops and consumers.
How does next() relate to Python's for loop mechanism?
Python for loops internally use the same protocol as next(), calling PyIter_Next to advance the iterator and catching StopIteration to terminate the loop. Using next() explicitly provides manual control over this same mechanism, allowing item‑by‑item processing outside of standard loop constructs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →