Remove items from a Python list while iterating it
This post will discuss how to remove items from a Python List while iterating it.
It is not recommended removing items from a list within a loop as this might cause the list to skip a few items and lead to incorrect output. This happens because removing items from the list while iterating changes the index and its length.
|
1 2 3 4 5 6 7 8 9 |
if __name__ == '__main__': nums = [1, 2, 3, 4, 5] for x in nums: nums.remove(x) print(nums) |
This post provides an overview of some available alternatives to avoid this non-deterministic behavior.
1. Using List Comprehension
You can use a list comprehension to create a new list containing only the desired items:
|
1 2 3 4 5 6 7 |
if __name__ == '__main__': nums = [1, 2, 3, 4, 5] odd = [x for x in nums if x & 1] print(odd) |
This works fine. However, it does not modify the input list in-place but creates a new list instead. This might cause issues when there are other references to the list which need updating. Fortunately, in Python, you can simply alter the list in-place by assigning to the slice [:].
|
1 2 3 4 5 6 7 |
if __name__ == '__main__': nums = [1, 2, 3, 4, 5] nums[:] = [x for x in nums if x & 1] print(nums) |
2. Using itertools module
In Python 3, you could also use the itertools module instead of list comprehension. It has a filterfalse() function, which filters elements from the list for which the predicate is False.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
from itertools import filterfalse def iseven(x): return x & 1 == 0 if __name__ == '__main__': nums = [1, 2, 3, 4, 5] nums[:] = filterfalse(iseven, nums) print(nums) |
3. Creating Copy of List
Here, the idea is to iterate over a copy of the list and then modify the original list as required. Here’s a working example:
|
1 2 3 4 5 6 7 8 9 10 |
if __name__ == '__main__': nums = [1, 2, 3, 4, 5] for x in list(nums): if x & 1 == 0: nums.remove(x) print(nums) |
4. Iterate Backwards
Another plausible way is to iterate backward in the list and remove the elements from it. This way, nothing is skipped. This approach has a major advantage over the other approaches as it does not create any copies of the list, and does the job in a single pass and in-place.
|
1 2 3 4 5 6 7 8 9 10 |
if __name__ == '__main__': nums = [1, 2, 3, 4, 5] for x in reversed(range(len(nums))): if x & 1 == 0: nums.remove(nums[x]) print(nums) |
That’s all about removing items from a Python list while iterating it.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)