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?

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.

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 article has been dead for over six months. Start a new discussion instead.