I lost a little bit of time in this Python for statement:
class MyListContainer:
def __init__(self):
self.list = []
def purge(self):
for object in self.list:
if (object.my_cond()):
self.list.remove(object)
return self.list
container = MyListContainer()
# now suppose both obj.my_cond() return True
obj1 = MyCustomObject(par)
obj2 = MyCustomObject(other_par)
container.list = [obj1, obj2]
# returning not an empty list but [obj2]
container.purge()
It doesn’t work as I expected because when the cycle in “purge” delete the first object in list the second one is shifted to the beginning of the list and the cycle is ended.
I solved duplicating self.list before the for cycle:
...
local_list = self.list[:]
for object in local_list:
...
I suppose that the for statement stop working because I’m changing the length of the original list. Can someone clarify this point ?
And is there a more “elegant” way to solve this problem ? If I have more than few elements inside the list, duplicating it every time does not seem a good idea.
Maybe the filter() function is the right one but i whish to have some other approach if any.
I’m a newbie.
To summarize your useful answers:
- Never edit a list you are looping
- Duplicate the list or use list comprehensions
- Duplicating a list could not waste your memory or in this case who’s mind about it
Filter (or list comprehension) IS the way to go. If you want to do it inplace, something like this would work:
Or alternatively, the purge list can be made with a comprehension, a shortcut version looks like: