Python: Remove elements from a list while iterating

This article will discuss different ways to delete elements from a list while iterating over it.


Table of Contents

Remove elements from list in for loop

Suppose we have a list of numbers,

list_of_num = [51, 52, 53, 54, 55, 56, 57, 58, 59]

We want to delete elements from the list while iterating over it, based on some conditions like all occurrences of 54 and 55. For this, we need first to create a copy of the list, and then we will iterate over that copied list. Then for each element, we will check if we want to delete this element or not. If yes, then delete that element from the original list using the remove() function. For example

list_of_num = [51, 52, 53, 54, 55, 56, 57, 58, 59]

for elem in list(list_of_num):
    if elem == 54 or elem == 55:
        list_of_num.remove(elem)

print(list_of_num)

Output

[51, 52, 53, 56, 57, 58, 59]

It deleted all the occurrences of 54 and 55 from the list while iterating over it. But now the main question that comes to mind is why we need to create a copy of the list initially.

Why can’t we just iterate over the original list and delete elements while iterating?

When we delete an element from a list using the remove() function in Python, it changes the remaining elements’ indexing. So if we are iterating over a list and we deleted an element from it while iterating over it, it will cause iterator invalidation and give unexpected results. Let’s understand by an example,

list_of_num = [51, 52, 53, 54, 55, 56, 57, 58, 59]

for elem in list_of_num:
    if elem == 54 or elem == 55:
        list_of_num.remove(elem)

print(list_of_num)

Output

[51, 52, 53, 55, 56, 57, 58, 59]

 

In this example, we were trying to delete 54 & 55 from the list while iterating over it. When we deleted 52, it internally shifted the indexing of all the elements after 52, and our iterator becomes invalid. Due to this, during the next iteration, it picks the element after 55 and skips the 55. So 54 got deleted, but 55 was skipped.

Therefore while deleting an element from the list while iterating, we need to make sure that we are iterating over the copy and removing elements from the original list to avoid iterator invalidation.

Remove elements from a list while iterating using list comprehension

We can iterate over the list and select elements we want to keep in the new list using list comprehension. Then we can assign the new list to the same reference variable, which was part to the original list. For example,

list_of_num = [51, 52, 53, 54, 55, 56, 57, 58, 59]

# Remove all occurrences of 54 & 55 from list
list_of_num = [num for num in list_of_num if num != 54 and num !=55 ]

print(list_of_num)

Output:

[51, 52, 53, 56, 57, 58, 59]

It created a new list, and then we assigned the new list back to the same reference variable. So it gave an effect that we have removed elements from the list while iterating over it. But internally, it created a new list.

Remove elements from a list while iterating using filter() function

Filter() function accepts two arguments,

  • First is a Lambda function or any other function
  • Second is the list from which we want to delete elements

It iterates over all the elements from the list and applies the given function over each list element. During iteration, it yields the elements for which the given function returns True. So we can use the filter() function to filter elements from a list while iterating over it. For example

list_of_num = [51, 52, 53, 54, 55, 56, 57, 58, 59]

# Remove all occurrences of 54 & 55 from list
list_of_num = list(filter(lambda num: num != 54 and num !=55,
                          list_of_num)
                   )

print(list_of_num)

Output:

[51, 52, 53, 56, 57, 58, 59]

As the first argument to the filter() function, we provided a Lambda function that checks if a given value is not equal to 54 or 55. If yes, then returns True otherwise False. As the second argument, we provided a list from which we want to delete the elements. Filter() function iterated over all the list elements and passed each item to the lambda function. Elements for which Lambda function return True were added to a new list. Then we assigned the new list to the same reference variable.

We created a new list by filtering the contents from the original list and then assigned it to the same variable. It gave an effect that we have deleted elements from the list while iterating.

Summary

We can delete multiple elements from a list while iterating, but we need to make sure that we are not invalidating the iterator. So either we need to create a copy of the list for iteration and then delete elements from the original list, or we can use the list comprehension or filter() function to do the same.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top