StopIteration Exception in Python Explained
StopIteration happens when an iterator has no more values to return.
This does not always mean something is broken. In Python, StopIteration is a normal signal used to say, “there are no more items.”
Beginners usually see it when:
- calling
next()too many times - using a
while Trueloop with an iterator - reusing an iterator that is already finished
- raising
StopIterationmanually inside a generator
If you use a for loop, Python usually handles this for you automatically. The exception becomes visible when you call next() yourself and do not handle the end of the iterator.
Quick fix
If you are calling next() manually, catch StopIteration:
numbers = iter([1, 2])
try:
while True:
print(next(numbers))
except StopIteration:
print("No more items")
Output:
1
2
No more items
Use try-except when you call next() yourself. In a for loop, Python handles StopIteration automatically.
What StopIteration means
StopIteration is raised when an iterator has no more values to give.
Important points:
- It is part of normal Python iteration
- It does not always mean there is a bug
- It is how Python knows an iterator is finished
For example, a list can be turned into an iterator with iter(). Each call to next() gets one item. When there are no items left, Python raises StopIteration.
If iterators are new to you, see iterators and iterable objects explained.
When beginners usually see this error
You will usually run into StopIteration in these situations:
- Calling
next()too many times - Reading past the end of a custom iterator
- Raising
StopIterationdirectly inside a generator - Using iterator code without checking when it is finished
A very common example is this:
numbers = iter([10, 20])
print(next(numbers))
print(next(numbers))
print(next(numbers)) # No more values left
The third call fails because the iterator is already exhausted.
Example that causes StopIteration
Here is a short example that raises the exception:
numbers = iter([1, 2])
print(next(numbers))
print(next(numbers))
print(next(numbers))
Output:
1
2
Traceback (most recent call last):
...
StopIteration
What happens here:
iter([1, 2])creates an iterator- the first
next(numbers)returns1 - the second returns
2 - the third has nothing left to return, so Python raises
StopIteration
Why for loops usually do not crash
A for loop uses next() behind the scenes.
For example:
numbers = [1, 2]
for number in numbers:
print(number)
Output:
1
2
This loop stops cleanly because Python catches StopIteration internally.
That is why normal for loops do not usually show this error. The loop keeps calling next() until the iterator is finished, then it stops.
This is one reason for loops are often safer than manual iterator code.
How to fix it when using next()
Wrap next() in try-except
If you want to keep calling next() yourself, catch the exception:
numbers = iter([1, 2])
while True:
try:
value = next(numbers)
print(value)
except StopIteration:
print("Finished")
break
Output:
1
2
Finished
Use a default value with next()
You can avoid the exception by giving next() a default value:
numbers = iter([1, 2])
print(next(numbers, None))
print(next(numbers, None))
print(next(numbers, None))
Output:
1
2
None
The third call returns None instead of raising StopIteration.
This is often the simplest fix when None is an acceptable “no more data” value.
Stop calling next() when the iterator is finished
In many cases, the best fix is to use a for loop instead of manual next() calls:
numbers = iter([1, 2])
for value in numbers:
print(value)
Output:
1
2
If your goal is just to loop through values, this is the easiest approach.
For more general exception handling, see how to handle exceptions in Python.
Generators and StopIteration
A generator is a function that yields values one at a time.
Generators end in a normal way when:
- they reach the end of the function
- they use
return
Beginners should not manually raise StopIteration inside a generator.
Bad example
def count():
yield 1
raise StopIteration
In modern Python, this is not the right way to end a generator.
Good example
def count():
yield 1
return
Or even more simply:
def count():
yield 1
When the generator finishes, Python handles the end correctly.
If you want to learn more, see generators in Python explained.
Debugging checklist
If you see StopIteration, check these things:
- Check where
next()is called - Check how many values the iterator contains
- Print values before the failing call
- See if a
forloop can replace manualnext()calls - If using a generator, remove manual
raise StopIteration
Useful debugging lines:
print(next(my_iter))
print(list(my_iter))
print(type(my_iter))
print(hasattr(my_iter, '__next__'))
What these can help you find:
print(type(my_iter))shows what kind of object you are working withprint(hasattr(my_iter, '__next__'))checks if it behaves like an iteratorprint(list(my_iter))shows remaining values, but it also consumes the iteratorprint(next(my_iter))helps test one step at a time
Be careful with this line:
print(list(my_iter))
It uses up the remaining items. After that, the iterator may already be exhausted.
Common causes
These are the most common reasons this exception appears:
- Calling
next()after the iterator is exhausted - Using
next()in awhile Trueloop without handling the end - Manually raising
StopIterationinside a generator - Reusing an iterator that has already been consumed
Reusing a consumed iterator
This is another common mistake:
numbers = iter([1, 2, 3])
for n in numbers:
print(n)
print("Second loop:")
for n in numbers:
print(n)
Output:
1
2
3
Second loop:
The second loop prints nothing because the iterator was already consumed in the first loop.
FAQ
Is StopIteration always an error?
No. It is a normal signal that an iterator is finished. It becomes a visible error only when your code does not handle it.
Why does a for loop not show StopIteration?
Because Python handles it internally to stop the loop.
How do I avoid StopIteration with next()?
Use try-except or pass a default value like next(my_iter, None).
Should I raise StopIteration in a generator?
No. In generators, use return or let the function end naturally.