Как и другие упомянутые pop и del, эффективные способы удаления элемента с указанным индексом. И все же просто ради завершения (поскольку то же самое можно сделать разными способами в Python):
Использование ломтиков (это не означает удаление элемента из исходного списка):
(Также это будет наименее эффективный метод при работе со списком Python, но он может быть полезен (но неэффективен, я повторяю) при работе с пользовательскими объектами, которые не поддерживают pop, но определяют __getitem__
):
>>> a = [1, 2, 3, 4, 5, 6]
>>> index = 3 # Only positive index
>>> a = a[:index] + a[index+1 :]
# a is now [1, 2, 3, 5, 6]
Примечание: Обратите внимание, что этот метод не изменяет список на месте, как pop
и del
. Вместо этого он создает две копии списков (один от начала до индекса, но без него (a[:index]
) и один после индекса до последнего элемента (a[index+1:]
)) и создает новый объект списка, добавляя оба. Затем он переназначается переменной списка (a
). Следовательно, старый объект списка разыменовывается и, следовательно, собирается сборщиком мусора (при условии, что на исходный объект списка не ссылаются никакие переменные, кроме a).
Это делает этот метод очень неэффективным и может также вызывать нежелательные побочные эффекты (особенно когда другие переменные указывают на исходный объект списка, который остается неизменным).
Спасибо @MarkDickinson за указание на это ...
Этот ответ переполнения стека объясняет концепцию нарезки.
Также обратите внимание, что это работает только с положительными индексами.
При использовании с объектами должен быть определен метод __getitem__
, и, что более важно, должен быть определен метод __add__
для возврата объекта, содержащего элементы из обоих операндов.
По сути, это работает с любым объектом, чье определение класса похоже на:
class foo(object):
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return foo(self.items[index])
def __add__(self, right):
return foo( self.items + right.items )
Это работает с list
, который определяет __getitem__
и __add__
методы.
Сравнение трех способов с точки зрения эффективности:
Предположим, что предопределено следующее:
a = range(10)
index = 3
Метод del object[index]
:
Безусловно, самый эффективный метод. Он будет работать со всеми объектами, которые определяют метод __del__
.
Разборка производится следующим образом:
Код:
def del_method():
global a
global index
del a[index]
Демонтажные:
10 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 DELETE_SUBSCR # This is the line that deletes the item
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
None
pop
метод:
Он менее эффективен, чем метод del, и используется, когда вам нужно получить удаленный элемент.
Код:
def pop_method():
global a
global index
a.pop(index)
Демонтажные:
17 0 LOAD_GLOBAL 0 (a)
3 LOAD_ATTR 1 (pop)
6 LOAD_GLOBAL 2 (index)
9 CALL_FUNCTION 1
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
Метод среза и добавления.
Наименее эффективный.
Код:
def slice_method():
global a
global index
a = a[:index] + a[index+1:]
Демонтажные:
24 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (index)
6 SLICE+2
7 LOAD_GLOBAL 0 (a)
10 LOAD_GLOBAL 1 (index)
13 LOAD_CONST 1 (1)
16 BINARY_ADD
17 SLICE+1
18 BINARY_ADD
19 STORE_GLOBAL 0 (a)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
None
Примечание: во всех трех разборках игнорируйте последние две строки, которые в основном return None
. Также первые две строки загружают глобальные значения a
и index
.