Remove items from one list in another
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 items from one list based on values in another looks simple, but the correct approach depends on what "remove" means for your data. Sometimes you want to drop every matching value, sometimes you want to preserve duplicate counts, and sometimes order matters more than raw speed. Python supports all of these cases, but the cleanest solution changes with the requirement.
Use a List Comprehension for the Basic Case
If you want to keep items from source that do not appear in blocked, a list comprehension is the most readable starting point.
Output:
This preserves the original order of source and removes every value that exists in blocked. For short lists, that is often enough. The downside is performance: item not in blocked scans the second list each time, so the total cost grows quickly as both inputs get larger.
Use a Set for Faster Membership Tests
When the second collection is large, convert it to a set first. Membership checks against a set are usually much faster.
This produces the same result, but scales better for large inputs. The key tradeoff is semantic, not technical: using a set ignores duplicate counts in blocked. If blocked contains [2, 2], a set still treats that as one blocked value.
Handle Duplicate Counts with Counter
Sometimes you want multiset subtraction rather than "remove every matching value." For example, if source is [1, 2, 2, 3] and blocked is [2], you may want the result to be [1, 2, 3] rather than [1, 3]. In that case, track how many times each value should be removed.
Output:
This version preserves order and removes only as many occurrences as requested by blocked.
Remove In Place Only When You Need Mutation
If other code holds a reference to the original list object, you may need to mutate it in place rather than creating a new list. Slice assignment is the safest way to do that while keeping the same list identity.
This changes the contents of numbers without creating a new external object. Avoid calling remove inside a loop over the same list, because that tends to skip elements or turn an easy task into fragile mutation logic.
Choose Based on Meaning, Not Just Speed
The best solution comes from the data rules:
- Use a list comprehension when the lists are small and clarity matters most.
- Use a set when you want fast membership tests and do not care about duplicate counts in the second list.
- Use
Counterwhen duplicates in the removal list carry meaning. - Use slice assignment only when you truly need to mutate the original list object.
Those distinctions matter more than memorizing one "Pythonic" answer.
Common Pitfalls
- Using a plain list membership check on very large inputs and then being surprised by poor performance.
- Converting the removal list to a set when duplicate counts are semantically important.
- Calling
list.removeinside a loop over the same list and skipping elements by accident. - Forgetting that a list comprehension creates a new list rather than mutating the original object.
- Choosing a fast approach that changes ordering when the original sequence order must be preserved.
Summary
- A list comprehension is the simplest way to remove all matching values while preserving order.
- Converting the second collection to a set improves performance for large membership checks.
- '
Counteris the right tool when removals should respect duplicate counts.' - Slice assignment lets you update a list in place without changing its identity.
- Pick the approach that matches the data semantics first, then optimize if needed.
Related reading
- Remove last item from array
- Remove multiple keys from Map in efficient way?
- Remove nodes from graph or reset entire default graph
- remove None value from a list without removing the 0 value
- Remove Last Two Characters in a String
- Remove pandas rows with duplicate indices
- Removing an activity from the history stack
- Removing an element from an Array Java

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.