Python
list manipulation
conditional filtering
programming
algorithm

Remove item from list based on condition

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Removing list items based on a condition is usually a filtering problem. In Python, the cleanest answer is often to build a new list with a comprehension, but sometimes you need to mutate the existing list in place. The right approach depends on whether other code holds a reference to that same list and whether order must be preserved.

Create a New Filtered List with a Comprehension

For most cases, the simplest pattern is:

python
1numbers = [1, 2, 3, 4, 5, 6]
2filtered = [x for x in numbers if x % 2 == 0]
3
4print(filtered)

This does not modify the original list. It creates a new one containing only the items that satisfy the condition.

If the goal is to remove items, flip the condition:

python
1numbers = [1, 2, 3, 4, 5, 6]
2without_small = [x for x in numbers if x >= 4]
3
4print(without_small)

This is the most readable option when immutability of the original list is acceptable.

Modify the Existing List In Place

Sometimes you must keep the same list object because other parts of the program reference it. In that case, replace the slice contents:

python
1numbers = [1, 2, 3, 4, 5, 6]
2numbers[:] = [x for x in numbers if x >= 4]
3
4print(numbers)

This keeps the same list object while updating its contents. That distinction matters when a caller passed in the list and expects it to be mutated rather than replaced.

Do Not Remove While Iterating Forward

One common bug is removing items from the list you are currently iterating:

python
1numbers = [1, 2, 3, 4, 5, 6]
2
3for x in numbers:
4    if x % 2 == 0:
5        numbers.remove(x)
6
7print(numbers)

This is dangerous because the list shifts while the loop is still moving forward. Elements can be skipped unexpectedly.

If you need iterative removal, loop over a copy:

python
1numbers = [1, 2, 3, 4, 5, 6]
2
3for x in numbers[:]:
4    if x % 2 == 0:
5        numbers.remove(x)
6
7print(numbers)

That works, but a comprehension is usually simpler and faster to reason about.

Remove Objects by a Predicate

The same pattern works for dictionaries or custom objects.

python
1users = [
2    {"name": "Alice", "active": True},
3    {"name": "Bob", "active": False},
4    {"name": "Cara", "active": True},
5]
6
7active_users = [user for user in users if user["active"]]
8print(active_users)

For custom objects:

python
1class User:
2    def __init__(self, name, active):
3        self.name = name
4        self.active = active
5
6
7users = [User("Alice", True), User("Bob", False), User("Cara", True)]
8users[:] = [u for u in users if u.active]
9
10print([u.name for u in users])

The condition can be as simple or as complex as you need. The important part is to keep the filter readable.

Use filter Only When It Helps

Python also provides filter, but it is often less readable than a comprehension:

python
1numbers = [1, 2, 3, 4, 5, 6]
2filtered = list(filter(lambda x: x >= 4, numbers))
3
4print(filtered)

This is valid, but list comprehensions are usually the more idiomatic choice in modern Python because the condition is easier to read inline.

Think About Semantics, Not Just Syntax

Before choosing the implementation, ask:

  • should the original list stay unchanged
  • do I need in-place mutation
  • is the condition simple enough to read
  • does item order need to be preserved

Most of the time, a new list is the safest answer. In-place mutation should be deliberate, not automatic.

Common Pitfalls

  • Removing items from a list while iterating over that same list in the forward direction.
  • Rebinding the list variable when the caller expected in-place mutation of the original object.
  • Using remove when the condition is predicate-based rather than value-based.
  • Writing a dense lambda in filter when a list comprehension would be clearer.
  • Forgetting that list filtering preserves order unless you add extra logic that changes it.

Summary

  • Use a list comprehension to create a new filtered list in the clearest way.
  • Use slice assignment when you need to mutate the existing list object in place.
  • Avoid removing elements while iterating directly over the same list.
  • Apply the same pattern to dictionaries and custom objects through a readable predicate.
  • Pick the approach based on mutation semantics, not just on brevity.

Related reading
Course
Intermediate
27 lessons
15 hours
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 course
Track 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.

Practice algorithms

All Rights Reserved.