How to remove item from a python list in a loop? [duplicate]
You can't remove items from a list while iterating over it. It's much easier to build a new list based on the old one:
y = [s for s in x if len(s) == 2]
hymloth and sven's answers work, but they do not modify the list (the create a new one). If you need the object modification you need to assign to a slice:
x[:] = [value for value in x if len(value)==2]
However, for large lists in which you need to remove few elements, this is memory consuming, but it runs in O(n).
glglgl's answer suffers from O(n²) complexity, because list.remove
is O(n).
Depending on the structure of your data, you may prefer noting the indexes of the elements to remove and using the del
keywork to remove by index:
to_remove = [i for i, val in enumerate(x) if len(val)==2]
for index in reversed(to_remove): # start at the end to avoid recomputing offsets
del x[index]
Now del x[i]
is also O(n) because you need to copy all elements after index i
(a list is a vector), so you'll need to test this against your data. Still this should be faster than using remove
because you don't pay for the cost of the search step of remove, and the copy step cost is the same in both cases.
[edit] Very nice in-place, O(n) version with limited memory requirements, courtesy of @Sven Marnach. It uses itertools.compress
which was introduced in python 2.7:
from itertools import compress
selectors = (len(s) == 2 for s in x)
for i, s in enumerate(compress(x, selectors)): # enumerate elements of length 2
x[i] = s # move found element to beginning of the list, without resizing
del x[i+1:] # trim the end of the list