Як і інші згадані поп і дель - це ефективні способи видалення елемента з даного індексу. І все-таки заради завершення (оскільки те саме можна зробити багатьма способами в Python):
Використання фрагментів (це не робить вилучення елемента з оригінального списку):
(Також це буде найменш ефективним методом при роботі зі списком Python, але це може бути корисно (але не ефективно, повторюю) під час роботи з визначеними користувачем об'єктами, які не підтримують pop, але все ж визначають a __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
.
O(n)
в часі.deque()
забезпечує ефективні операції з обох кінців, але не забезпечує вставки / огляди / видалення O (1) посередині.