When I am writing code in Python, I often need to remove items from a list or other sequence type based on some criteria. I haven't found a solution that is elegant and efficient, as removing items from a list you are currently iterating through is bad. For example, you can't do this:
for name in names:
if name[-5:] == 'Smith':
names.remove(name)
I usually end up doing something like this:
toremove = []
for name in names:
if name[-5:] == 'Smith':
toremove.append(name)
for name in toremove:
names.remove(name)
del toremove
This is innefficient, fairly ugly and possibly buggy (how does it handle multiple 'John Smith' entries?). Does anyone have a more elegant solution, or at least a more efficient one?
How about one that works with dictionaries?
Two easy ways to accomplish just the filtering are:
Using filter
:
names = filter(lambda name: name[-5:] != "Smith", names)
Using list comprehensions:
names = [name for name in names if name[-5:] != "Smith"]
Note that both cases keep the values for which the predicate function evaluates to True
, so you have to reverse the logic (i.e. you say "keep the people who do not have the last name Smith" instead of "remove the people who have the last name Smith").
Edit Funny... two people individually posted both of the answers I suggested as I was posting mine.