Skip to content

How to Remove Elements from a List Using del, pop() and remove() in Python

Learn how to use Python's del, pop(), and remove() methods to delete list elements by index or value, handle errors safely, and avoid common mistakes like modifying lists during iteration.

Python provides three distinct built-in ways to delete elements from a list: the del statement, the pop() method, and the remove() method. Each one targets elements differently, returns different results, and raises different errors when something goes wrong.

This guide explains how each method works, when to use one over the others, how to handle errors safely, and how to avoid common mistakes that lead to bugs in real-world code.

Using del for Index-Based Deletion

The del statement removes an element at a specific index without returning it. It is a statement, not a method, so it does not use parentheses:

nums = [10, 20, 30, 40]
del nums[1]
print(nums)

Output:

[10, 30, 40]

Deleting slices with del

One of the unique strengths of del is its ability to remove multiple elements at once using slice notation:

nums = [10, 20, 30, 40, 50]

del nums[1:3]
print(nums)

Output:

[10, 40, 50]
nums = [10, 20, 30, 40, 50, 60]

del nums[::2]
print(nums)

Output:

[20, 40, 60]

You can also use del to delete the entire list variable:

nums = [10, 20, 30]
del nums

Using pop() to Retrieve and Remove

The pop() method removes an element by index and returns the removed value. This makes it the right choice when you need to use the deleted element after removal:

nums = [10, 20, 30]

last = nums.pop()       # No argument removes the last element
print(last)
print(nums)

Output:

30
[10, 20]
first = nums.pop(0)     # Remove element at index 0
print(first)
print(nums)

Output:

10
[20]

Stack and queue operations with pop()

pop() is the standard tool for implementing stack and queue patterns in Python:

stack = [1, 2, 3]
stack.append(4)
top = stack.pop()
print(f"Popped from stack: {top}")
print(f"Stack: {stack}")

Output:

Popped from stack: 4
Stack: [1, 2, 3]
queue = [1, 2, 3]
first = queue.pop(0)
print(f"Popped from queue: {first}")
print(f"Queue: {queue}")

Output:

Popped from queue: 1
Queue: [2, 3]

Using remove() for Value-Based Deletion

The remove() method searches for a value and deletes its first occurrence. Unlike del and pop(), it does not require you to know the index:

fruits = ["apple", "banana", "apple", "cherry"]
fruits.remove("apple")
print(fruits)

Output:

['banana', 'apple', 'cherry']

Notice that only the first "apple" was removed. The second one at what was originally index 2 remains in the list.

Removing all occurrences of a value

A common mistake is assuming remove() deletes every instance of the value. It does not. If you need to remove all occurrences, you have two main options.

Option 1: A while loop with remove()

nums = [1, 2, 1, 3, 1]
while 1 in nums:
    nums.remove(1)
print(nums)

Output:

[2, 3]

This approach works but has O(n^2) time complexity because both the in check and remove() scan the list on every iteration.

nums = [1, 2, 1, 3, 1]
nums = [x for x in nums if x != 1]
print(nums)

Output:

[2, 3]

The list comprehension runs in O(n) time and is the preferred approach for removing all occurrences, especially in larger lists.

Error Handling

Each method raises a different exception when it fails, and understanding these differences is important for writing robust code.

del and pop() raise IndexError

nums = [10, 20, 30]

del nums[10]

Output:

IndexError: list assignment index out of range
nums = [10, 20, 30]

nums.pop(10)

Output:

IndexError: pop index out of range

remove() raises ValueError

nums = [10, 20, 30]

nums.remove(999)

Output:

ValueError: list.remove(x): x not in list

Writing safe deletion helpers

To avoid crashes from unexpected missing elements, wrap deletion calls with error handling:

def safe_pop(lst, index=-1, default=None):
    try:
        return lst.pop(index)
    except IndexError:
        return default

nums = [10, 20, 30]
result = safe_pop(nums, 10, default="Not found")
print(result)
print(nums)

Output:

Not found
[10, 20, 30]
nums = [1, 2, 3]
value_to_remove = 5

if value_to_remove in nums:
    nums.remove(value_to_remove)
else:
    print(f"{value_to_remove} not found in list")

Output:

5 not found in list

Common Mistake: Modifying a List While Iterating Over It

One of the most frequent bugs when removing elements from a list is modifying the list inside a for loop that is iterating over it:

nums = [1, 2, 3, 4, 5, 6]

for n in nums:
    if n % 2 == 0:
        nums.remove(n)

print(nums)

Output:

[1, 3, 5]

This appears to work here, but the behavior is unreliable. When you remove an element, the indices shift and the iterator can skip the next element. Consider a more problematic case:

nums = [2, 4, 6, 8]

for n in nums:
    if n % 2 == 0:
        nums.remove(n)

print(nums)

Output:

[4, 8]

Two elements survive because the loop skips over them after each removal shifts the list.

The correct approach is to build a new list with a comprehension or iterate over a copy:

nums = [2, 4, 6, 8]
nums = [n for n in nums if n % 2 != 0]
print(nums)

Output:

[]
nums = [2, 4, 6, 8]
for n in nums[:]:  # nums[:] creates a shallow copy
    if n % 2 == 0:
        nums.remove(n)

print(nums)

Output:

[]

Quick Comparison

Feature del list[i] pop(i) remove(x)
Targets by Index or slice Index Value
Returns the removed value No Yes No
Removes multiple elements Yes (via slicing) No No
Error on failure IndexError IndexError ValueError
Best for Bulk deletion, index-based removal Stack/queue ops, needing the value Deleting by content

When to Use Each Method

  • del: Choose this when you need to remove elements by index and do not need the removed value, or when you want to delete a slice of elements in a single operation.
  • pop(): Choose this when you need to both remove and use the removed value, such as in stack or queue patterns, or when processing items one at a time.
  • remove(): Choose this when you know the value you want to delete but not its position in the list. Remember that it only removes the first occurrence.

For removing all occurrences of a value or removing elements based on a condition, a list comprehension is almost always the most efficient and readable approach.

Navigation