Looping Over List And Removing Entries In Python
Solution 1:
I don't see why you wouldn't just construct a new list with the items you want to keep, since you don't seem to care about constructing a new list (after all, that is what copy
does).
So I would just do
example = [f for f in example if f >= 3]
If you do want to iterate over the list and change it, perhaps iterate over indices and go backwards:
for i inrange(len(example) - 1, -1, -1):
if example[i] < 3:
del example[i]
But that's a bit special, I would avoid it unless really necessary.
To show that you don't need silly example_1, example_2, old_example etc variables, consider:
# Here is a number of tests for things we want throw outdefsome_really_complicated_test_on_a_number(f):
... put any kind of code here andreturnTrueif we want to
delete the number...
TESTS = (
lambda f: f < 3,
lambda f: f > 16,
lambda f: (int(f) % 2) == 1, # Integer is odd
some_really_complicated_test_on_a_number,
# etc
)
Here's a function that takes a list and a test, prints the items with "accepting" and "rejecting", and returns a new list with the remaining items:
deffilter_with_prints(l, test):
result = []
for f in l:
if test(f):
print("Rejecting: {}".format(f))
else:
result.append(f)
print("Accepting: {}".format(f))
return result
And we can call a lot of tests like this:
example = [1., 2., 3., 4., 5., 6.]
fortestin TESTS:
example = filter_with_prints(example, test)
Solution 2:
You are right, the problem is that you are modifying the list you are iterating through during the loop. That's very inconsistent and leads to many errors. My question would be why you are specifically interested in removing items of the list rather than generating a new copy that meets your suggestions? Is there a specific requirement for that? Otherwise I would suggest to make a new copy of the list that meets your restrictions instead of modifying the input list. So, modifying your code:
example = [1.,2.,3.,4.,5.,6.]
new_list = []
for e in example:
if e >= 3.:
new_list.append(e)
print"Accepting:", e
else:
print"Removing: ", e
This is less error prone, but you could be more pythonic and use list comprehension for that:
new_list = [e for e in example if e >= 3.]
Edit: I see that the reason you want to remove items instead of creating new lists is that you are going through the list several times to filter the list. I still think that even in that case it is more readable, less error prone and not specially less efficient to create a new list each time. If efficiency was the problem and you had very large lists or something like that, I would try to only iterate through the list once and remove all non-valid items at the same loop. However, if you really want to remove items from the list, you can do as @RemcoGerlich says and go backwards iterating by index.
Post a Comment for "Looping Over List And Removing Entries In Python"