How to delete an element from a list while iterating over it in Python? [duplicate]

Best is usually to proceed constructively — build the new list of the items you want instead of removing those you don’t. E.g.:

L[:] = [el for el in L if el != 3]

the list comprehension builds the desired list and the assignment to the “whole-list slice”, L[:], ensure you’re not just rebinding a name, but fully replacing the contents, so the effects are identically equal to the “removals” you wanted to perform. This is also fast.

If you absolutely, at any cost, must do deletions instead, a subtle approach might work:

>>> ndel = 0
>>> for i, el in enumerate(list(L)):
...    if el==3:
...      del L[i-ndel]
...      ndel += 1

nowhere as elegant, clean, simple, or well-performing as the listcomp approach, but it does do the job (though its correctness is not obvious at first glance and in fact I had it wrong before an edit!-). “at any cost” applies here;-).

Looping on indices in lieu of items is another inferior but workable approach for the “must do deletions” case — but remember to reverse the indices in this case…:

for i in reversed(range(len(L))):
  if L[i] == 3: del L[i]

indeed this was a primary use case for reversed back when we were debating on whether to add that built-in — reversed(range(... isn’t trivial to obtain without reversed, and looping on the list in reversed order is sometimes useful. The alternative

for i in range(len(L) - 1, -1, -1):

is really easy to get wrong;-).

Still, the listcomp I recommended at the start of this answer looks better and better as alternatives are examined, doesn’t it?-).

Leave a Comment