Back to Blog
Python

Python del: Remove List Elements by Index or Slice

Learn how to use Python's del statement to remove list elements by index or slice, including in-place mutation behavior, comparisons with pop() and remove(), and practical examples.

list manipulationdel statementPython listselement removalin-place deletion
Python list with an element being removed by the del statement, showing index-based deletion.

When you need to remove an element from a Python list by its position, the del statement is the most direct tool. Unlike methods that return the removed value, del deletes the target from the list and modifies the list in place. This article explains the del statement for list element removal: its syntax, behavior, and when it is a better choice than alternatives like pop() and remove().

The Basic del Syntax for Lists

The del statement operates on any Python object that supports deletion, and lists are a primary example. To delete a single element, reference the list followed by the index in square brackets:

colors = ["red", "green", "blue"] del colors[1] print(colors) # ['red', 'blue']

Here, del colors[1] removes the element at index 1 ("green"). The list is shortened by one, and all subsequent elements shift left. The del statement does not return the deleted value; if you need that value, use pop() instead.

Indexing works with negative numbers as well, so del colors[-1] removes the last element of the list. This is useful when you know the position relative to the end of the list.

Deleting a Slice of Elements

del can also remove a contiguous range of elements using slice notation. This is a feature that pop() and remove() do not provide.

numbers = [10, 20, 30, 40, 50] del numbers[1:3] print(numbers) # [10, 40, 50]

The slice [1:3] includes indices 1 and 2, so 20 and 30 are removed. The list is mutated in place, and the remaining elements are reindexed.

You can also delete every element in the list with a full slice:

items = [1, 2, 3] del items[:] print(items) # []

This clears the list while keeping the same list object. If you instead write items = [], you create a new list and rebind the variable, which can matter when other references to the original list exist.

Using del with a Step in the Slice

Slice deletion supports a step value, which allows you to delete non-contiguous elements in a single operation. For example, to remove every other element:

values = [1, 2, 3, 4, 5, 6] del values[::2] print(values) # [2, 4, 6]

The slice [::2] selects indices 0, 2, and 4, and del removes those elements. This is a concise way to filter a list by position, though it can be less readable than a list comprehension if the selection logic is complex.

del vs pop() vs remove()

Choosing the right deletion method depends on what information you have and what you need to do with the removed element.

MethodWhat it deletesReturns valueError behavior
del list[i]Element at index iNoIndexError if i is out of range
del list[a:b]Slice from a to bNoNo error for out-of-range slice bounds; Python clamps them
list.pop(i)Element at index iYesIndexError if i is out of range
list.remove(x)First element equal to xNoValueError if x is not present

Use del when you know the index or slice and do not need the removed value. Use pop() when you need the removed value for further processing, such as implementing a stack. Use remove() when you know the value but not the position, and you only want to remove the first occurrence.

Runtime Cost and Memory Behavior

Deleting an element from a list has a time complexity of O(n) because all elements after the deleted position must be shifted left in memory. This is true for del, pop(), and remove() alike. If you are deleting from the end of the list, the operation is O(1) because no shifting occurs.

For applications that require frequent deletion from the beginning or middle of a collection, a list may not be the ideal data structure. A collections.deque supports efficient deletion from either end, but deletions in the middle are not efficient. If you need both indexed access and frequent middle deletion, consider whether a different structure such as a balanced tree or a custom linked list is warranted, though these come with their own tradeoffs.

When you delete a slice, Python releases the references to the removed objects, making them eligible for garbage collection if no other references exist. This is relevant in long-running processes where holding onto large lists unnecessarily can increase memory pressure.

Common Errors and Pitfalls

One frequent mistake is attempting to delete an element from a list while iterating over it. Modifying the list during iteration can cause elements to be skipped or an IndexError to be raised.

# Problematic: skipping elements numbers = [1, 2, 3, 4, 5] for i, n in enumerate(numbers): if n % 2 == 0: del numbers[i]

This loop skips the element after each deletion because the list shrinks while the loop index continues. A safer approach is to iterate over a copy of the list, or to build a new list with a comprehension:

numbers = [1, 2, 3, 4, 5] numbers = [n for n in numbers if n % 2 != 0]

Another pitfall is using an out-of-range integer index: del items[10] raises IndexError when the list has fewer than 11 items. This is different from slice deletion, where out-of-range slice bounds are clamped and do not raise an error. Unlike remove(), which raises ValueError when a value is absent, del by index only works with valid indices. Check that the index is valid before calling del, or catch the exception if the index may be invalid.

When del Is the Right Choice in Production Code

In production code, del is most useful when you need to remove elements by position as part of an algorithm, such as when processing a queue represented as a list, or when cleaning up specific entries from a data structure. It is also the standard way to delete a slice, since no built-in method offers that functionality directly.

However, for most filtering tasks, a list comprehension or the filter() function is more readable and avoids the risk of index errors. Use del when the operation is genuinely about position-based deletion rather than value-based filtering.

When working with large lists, be aware of the O(n) shifting cost and consider whether you can process the list from the end to the beginning. Deleting from the end is cheaper, and iterating backward avoids the index-shift problem entirely:

numbers = [1, 2, 3, 4, 5] for i in range(len(numbers) - 1, -1, -1): if numbers[i] % 2 == 0: del numbers[i]

This approach modifies the list in place without skipping elements, and it avoids creating a new list. It is a useful pattern when you need to keep the same list object for other references.

Python del: Remove List Elements by Index or Slice | RYUSLOG DEV