Question

I inherited a UserList class from list and implemented the following method to remove entries which are marked deleted

def purge_deleted(self):
    for element in list.__iter__(self):
        if ele.mark_deleted < 1:
            self.remove(element)

the element in itself is a complicated entity having methods overriding comparison operators

Questions

  1. Will the above code successfully work in removing the objects?
  2. How does python internally works to remove the elements from the list?
  3. Will it not create a problem when we simultaneously iterate and modify the same list?
Was it helpful?

Solution

You will end up skipping elements, as the iterator is not updated to allow for removed elements.

You can iterate over the list in reverse to avoid that problem:

def purge_deleted(self):
    for element in reversed(self):
        if ele.mark_deleted < 1:
            self.remove(element)

What happens if you don't reverse is that the iterator index increments regardless of any removals; if you remove the item at index 1, the iterator moves on to item 2 even though that was item 3 before the removal (skipping the item previously at index 2).

When you remove items in reverse however, the index moves from 1 to 0, and any removals happened 'behind' the current index. It doesn't matter anymore if item 1 was deleted or not.

The reversed() iterator will make use of any custom __reversed__ hook, if present.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top