Podobnie jak inni wspomniano pop i del są to skuteczne sposoby, aby usunąć element o danym indeksie. Jednak tylko ze względu na ukończenie (ponieważ to samo można zrobić na wiele sposobów w Pythonie):
Używanie plasterków (nie powoduje to usunięcia elementu z oryginalnej listy):
(Również będzie to najmniej wydajna metoda podczas pracy z listą Python, ale może to być przydatne (ale nie wydajne, powtarzam) podczas pracy z obiektami zdefiniowanymi przez użytkownika, które nie obsługują pop, ale definiują 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]
Uwaga: należy pamiętać, że ta metoda nie modyfikuje listy w miejscu jak pop
i del
. Zamiast tego tworzy dwie kopie list (jedną od początku do indeksu, ale bez niego ( a[:index]
), a drugą po indeksie do ostatniego elementu ( a[index+1:]
)) i tworzy nowy obiekt listy, dodając oba. Jest to następnie przypisywane do zmiennej listy ( a
). Stary obiekt listy jest zatem wyrejestrowany, a zatem zbierany w pamięci (pod warunkiem, że do oryginalnego obiektu listy nie odwołuje się żadna zmienna inna niż a).
To sprawia, że ta metoda jest bardzo nieefektywna i może również powodować niepożądane skutki uboczne (szczególnie, gdy inne zmienne wskazują oryginalny obiekt listy, który pozostaje niezmodyfikowany).
Dzięki @MarkDickinson za zwrócenie uwagi na to ...
Ta odpowiedź na przepełnienie stosu wyjaśnia pojęcie krojenia.
Zauważ też, że działa to tylko z dodatnimi indeksami.
Podczas używania z obiektami __getitem__
metoda musi zostać zdefiniowana, a co ważniejsze, __add__
metoda musi zostać zdefiniowana, aby zwrócić obiekt zawierający elementy z obu argumentów operacji.
Zasadniczo działa to z każdym obiektem, którego definicja klasy przypomina:
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 )
Działa to przy użyciu list
definicji __getitem__
i __add__
metod.
Porównanie trzech sposobów pod względem wydajności:
Załóżmy, że wstępnie zdefiniowano następujące elementy:
a = range(10)
index = 3
del object[index]
Metoda:
Zdecydowanie najbardziej wydajna metoda. Działa to ze wszystkimi obiektami, które definiują __del__
metodę.
Demontaż wygląda następująco:
Kod:
def del_method():
global a
global index
del a[index]
Demontaż:
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
metoda:
Jest mniej wydajny niż metoda del i jest używany, gdy trzeba uzyskać usunięty element.
Kod:
def pop_method():
global a
global index
a.pop(index)
Demontaż:
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
Metoda wycinania i dodawania.
Najmniej wydajny.
Kod:
def slice_method():
global a
global index
a = a[:index] + a[index+1:]
Demontaż:
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
Uwaga: We wszystkich trzech demontażach zignoruj dwie ostatnie linie, które w zasadzie są return None
. Również pierwsze dwa wiersze ładują wartości globalne a
i index
.
O(n)
w czasie.deque()
zapewnia wydajne operacje na obu końcach, ale nie zapewnia wstawiania / wyszukiwania / usuwania O (1) w środku.