Безопасное использование метода удаления в Python

Я унаследовал класс UserList из списка и реализовал следующий метод для удаления записей, помеченных как удаленные

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

элемент сам по себе является сложной сущностью, имеющей методы, переопределяющие операторы сравнения

Вопросы

  1. Будет ли приведенный выше код успешно работать при удалении объектов?
  2. Как Python внутренне работает, чтобы удалить элементы из списка?
  3. Не создаст ли это проблемы, когда мы одновременно выполняем итерацию и изменяем один и тот же список?

1 ответ

Решение

В итоге вы пропустите элементы, так как итератор не обновляется, чтобы учесть удаленные элементы.

Вы можете перебрать список в обратном порядке, чтобы избежать этой проблемы:

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

Что произойдет, если вы не поменяете местами, так это то, что индекс итератора увеличивается независимо от удаления; если вы удаляете элемент с индексом 1, итератор переходит к элементу 2, хотя это был элемент 3 до удаления (пропуская элемент ранее с индексом 2).

Однако когда вы удаляете элементы в обратном порядке, индекс перемещается с 1 на 0, и любое удаление происходило "позади" текущего индекса. Больше не имеет значения, был ли удален элемент 1 или нет.

reversed() итератор будет использовать любой пользовательский __reversed__ крючок, если есть.

Другие вопросы по тегам