Python’s built-in next() retrieves one item from an iterator and advances that iterator’s state. Call next(iterator) when exhaustion should raise StopIteration, or call next(iterator, default) when reaching the end is an ordinary outcome. The function is especially useful for reading one value lazily without materializing an entire collection.
Quick answer
Turn an iterable into an iterator with iter(), then call next(). Use a second argument for a fallback instead of catching StopIteration when absence is expected. The official next() documentation defines both forms and the iterator protocol.

Get items from an iterator
A list is iterable but is not itself an iterator. Call iter() to create an iterator, then request values one at a time.
values = ["first", "second"]
iterator = iter(values)
print(next(iterator))
print(next(iterator))
Each call advances the same iterator. A second name pointing at that iterator observes the same consumed state; creating a new iterator over the list starts from the beginning.
Handle StopIteration
When an iterator has no item left, the one-argument form raises StopIteration. A for loop handles this protocol internally, which is why ordinary loops do not need a manual exception block.
iterator = iter([1])
print(next(iterator))
try:
print(next(iterator))
except StopIteration:
print("iterator is exhausted")
Catch the exception when exhaustion is the boundary of a custom algorithm. Do not use a broad exception handler that could hide an unrelated error raised while producing the next item.
Provide a default value
The two-argument form returns the default instead of raising when the iterator is exhausted. Choose a default that cannot be confused with a real item, or use a unique sentinel.
missing = object()
iterator = iter([])
value = next(iterator, missing)
if value is missing:
print("no value")
None is convenient when it cannot be a valid result. A sentinel is safer when None could legitimately appear in the data.
Find the first matching item lazily
Combine next() with a generator expression to stop at the first match. This avoids building a list of every matching item when the caller needs only one.
values = [3, 7, 10, 12]
first_even = next((value for value in values if value % 2 == 0), None)
print(first_even)
The generator stops after finding ten. If no value matches, the default None is returned. Document whether “no match” is normal or should be an error.
Understand custom iterators
An iterator implements __iter__() returning itself and __next__() returning the next value or raising StopIteration. This protocol lets next(), for, and many built-in tools work with the same object.
class CountTo:
def __init__(self, limit):
self.current = 0
self.limit = limit
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
value = self.current
self.current += 1
return value
counter = CountTo(2)
print(next(counter))
print(next(counter))
Keep iterator state private and make exhaustion deterministic. A custom iterator that returns a value after exhaustion violates the protocol and can make callers loop forever.
Choose next or a loop
Use next() for one-item reads, lazy first-match selection, and explicit iterator protocols. Use a loop when every value needs processing, and use a list when random access or repeated traversal is required. The smallest correct abstraction makes consumption behavior easier to review.
Use a sentinel when None is valid
If None can be a real item, pass a unique object as the default and compare by identity. This avoids confusing “the iterator produced None” with “the iterator was exhausted.”
missing = object()
iterator = iter([None])
value = next(iterator, missing)
if value is missing:
print("empty")
else:
print("item:", value)
A sentinel should remain private to the helper. Returning it to unrelated callers would expose an implementation detail rather than a meaningful result.
Do not reuse an exhausted iterator accidentally
Lists and tuples can create fresh iterators, but generators and many custom iterators are one-shot. If a function accepts an iterable and needs to traverse it more than once, decide whether to materialize it or redesign the function to consume it once. Calling next() in a logging statement can change what later code receives.
Keep StopIteration inside the iterator boundary
A generator function uses yield, and its normal return becomes iterator exhaustion. Do not let a manually raised StopIteration escape from arbitrary generator body logic; use a normal return for the generator’s end and let the protocol signal completion.
When an iterator raises an unrelated exception while producing a value, do not replace it with a default. A default should represent exhaustion only, not hide a failed data source.
Use next with a file or stream carefully
Reading the first line of a file with next(iter(file), default) is lazy, but the file still has a lifetime and cursor. Keep the file open for the duration of the read and close it with a context manager. For a network or database cursor, treat a missing row and a failed connection as different outcomes.
from io import StringIO
stream = StringIO("first\nsecond\n")
first_line = next(stream, "")
print(first_line.strip())
Do not call next() on a value that is merely iterable without first obtaining an iterator. A list, string, and dictionary can be passed to iter(), but they do not expose the iterator protocol directly through a __next__ method.
Keep the first-match predicate pure
A generator expression used with next() can stop early, which is efficient, but its predicate should not perform an irreversible side effect unless that side effect is part of the documented search. If the predicate raises, let the error surface rather than converting it into the “not found” default.
For related iteration patterns, see set iteration, break, and directory traversal.
Make the exhaustion policy visible
Choose one policy at each call site: return a default for an expected empty result, or allow StopIteration to signal a programming or data contract failure. Naming that choice in a helper prevents callers from guessing what a missing item means.
Frequently Asked Questions
What does next() do in Python?
next() asks an iterator for its next value and advances the iterator state.
How do I avoid StopIteration with next()?
Pass a second argument such as None or a private sentinel when an exhausted iterator should produce a fallback value.
How do I find the first matching item?
Use next() with a generator expression and a default so values are tested lazily until the first match is found.
What is the difference between an iterable and an iterator?
An iterable can create an iterator with iter(), while an iterator also exposes __next__() and keeps consumption state.