How to remove items from a list while iterating?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Removing elements from a list while iterating over that same list is a classic source of skipped items and confusing bugs. The problem is not that Python forbids mutation. The problem is that list indices shift as items are removed, while the loop keeps advancing.
Why Forward Iteration Goes Wrong
Consider this code:
It may appear to work for some inputs, but the logic is fragile. When an item is removed, later elements slide left, and the loop's next position may skip over one of them.
That is why "remove while iterating" is usually really a question about choosing the right pattern.
Best Option: Build a New Filtered List
If you do not need to mutate the list in place, the cleanest solution is usually to create a new list.
This is readable, efficient, and avoids index-shifting issues entirely. In Python, this is often the most idiomatic answer.
If you want to keep the same list object but replace its contents, use slice assignment:
That updates the existing list in place, which matters if other code holds references to it.
If You Must Remove In Place, Iterate Backward by Index
When true in-place removal is required, iterate over indices in reverse order.
This works because deleting an item only affects elements to its right, and you have already processed those.
Using del numbers[index] is also clearer here than remove, because you already know the exact position you want to delete.
Iterating Over a Copy Is Safe but Often Less Direct
Another safe pattern is to loop over a shallow copy and mutate the original list.
This is valid, but it can be slower for large lists, especially when repeated remove calls search for the value each time. It is often acceptable for small scripts, but list comprehension or backward-index deletion is usually more explicit about intent.
Choose the Pattern Based on What Must Stay Stable
The right solution depends on whether you care about:
- preserving the original list object
- preserving order
- minimizing extra memory
- writing the clearest code
For most code:
- use a new filtered list if mutation is not required
- use slice assignment if you need to keep the same list object
- use backward index iteration if true in-place deletion is required
That decision is more important than memorizing one trick.
Avoid remove in Value-Based Loops for Repeated Matches
One subtle issue with remove is that it deletes the first matching value, not necessarily the specific occurrence you were conceptually looking at. That can matter when duplicate values are present.
Backward index deletion avoids that ambiguity because it operates on positions, not "first matching value" semantics.
Common Pitfalls
- Removing from a list during forward iteration and assuming the loop will still visit every element.
- Using
removewhen duplicates are present and position matters. - Forgetting that list comprehension returns a new list unless you use slice assignment.
- Choosing an in-place mutation pattern when a new filtered list would be simpler.
- Using repeated
removecalls in performance-sensitive code without noticing the extra cost.
Summary
- Forward iteration plus removal is error-prone because list indices shift.
- The cleanest solution is often to build a new filtered list.
- Use slice assignment when you want to keep the same list object.
- If in-place deletion is required, iterate backward by index.
- Prefer a pattern that matches the real requirement rather than forcing mutation into the loop.
Related reading
- How to remove items from a list while iterating?
- How to remove multiple indexes from a list at the same time?
- How to remove multiple items from a list in just one statement?
- How to remove nodes from TensorFlow graph?
- How to remove specific elements in a numpy array
- How to remove specific message from queue in rabbitmq
- how to represent graphs /trees in python and how to detect cycles?
- How to requeue messages in RabbitMQ

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.