Iterating over a list, possibly deleting elements. It's the bane of my existence. Suppose, for instance, we have a list of numbers, and want to iterate over it and delete each and every odd one. Sounds simple, right?

Sorta. It's trivial, but the code you end up with is pretty gruesome.

``````>>> nums = [1.0,2.0,3.0,4.0,5.0]
>>> for n in range(len(nums)-1,-1,-1):
# Same as saying "if nums[n] is odd"
if nums[n] % 2 != 0:
del nums[n]

>>> print nums
[2.0, 4.0]``````

Surely there's a cleaner way to do that loop? Anyone?

4
Contributors
5
Replies
6
Views
10 Years
Discussion Span
Last Post by jrcagle

Try a list comprehension:

``````>>> nums = [1.0,2.0,3.0,4.0,5.0]
>>> evens = [x for x in nums if x%2==0]
>>> evens
[2.0, 4.0]
>>>``````

Can you tell me, why it is needed to delete from the list?

Is it not good enough to construct another list with the desired members, and assign it to the original list?

Because if you create a new list and assign it to the old one, you're creating an un-needed variable.

del nums[1::2]

If you are determined to iterate through the original list ... and there are times when that's appropriate ... then you must iterate through a copy of the list:

``````>>> nums = [1.0,2.0,3.0,4.0,5.0]
>>> for n in nums[:]:
if n % 2 == 1: # better way to say 'is odd'
nums.remove(n)``````

By iterating through the copy, you avoid the problem of trying to delete from a list under iteration.

But in general, I endorse BearofNH's solution as the cleanest. It's scarcely more expensive to use a list comprehension than to iteration through a list to begin with, and a new variable need not be created:

``````>>> nums = [1.0,2.0,3.0,4.0,5.0]
>>> nums = [x for x in nums if x % 2 == 1]``````

Jeff

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.