В чем разница между методами pop, remove и оператором del в списках Python
Что проверяют
Знаете ли вы разницу не на уровне «одно по индексу, другое по значению», а по возвращаемому значению, исключениям и сложности. Следом часто просят удалить элементы из списка в цикле или спрашивают, почему pop(0) плохая идея для очереди.
Как отвечать
pop(i=-1): метод, удаляет элемент по индексу и возвращает его. Без аргумента берёт последний. На пустом списке или индексе вне диапазона бросаетIndexError. С конца работает за O(1), из начала или середины за O(n), потому что хвост списка сдвигается;remove(x): метод, ищет первый элемент, равныйxпо==, и удаляет его. ВозвращаетNone, при отсутствии значения бросаетValueError. Всегда O(n): поиск плюс сдвиг;del: оператор языка, а не метод. Удаляет по индексу (del a[2]) или по срезу (del a[1:4],del a[::2]), ничего не возвращает, при неверном индексе даётIndexError. Под капотом вызывает__delitem__.
Важная деталь: del a без индекса удаляет не список, а имя. Сам объект освободится, когда на него не останется ссылок, и если было b = a, список продолжит жить.
Хорошо добавить практику. Для очереди берите collections.deque с popleft() за O(1). Чтобы убрать все вхождения значения, пишите генератор списка [x for x in a if x != v], а не цикл с remove. Полная очистка это a.clear() или del a[:], и в отличие от a = [] она меняет тот же объект, который видят другие ссылки.
Где спотыкаются
Удаляют элементы из списка, по которому идут циклом for. Индексы смещаются, и соседний элемент пропускается. Нужна копия a[:] или новый список.
Пишут x = a.remove(3) и ждут удалённое значение, а получают None. Возвращает элемент только pop.
Забывают, что remove сравнивает через ==. Список [1, True] после remove(True) потеряет единицу, потому что 1 == True.