Come altri citati pop e del sono i modi efficienti per rimuovere un elemento di un determinato indice. Tuttavia, solo per motivi di completamento (dal momento che la stessa cosa può essere fatta in molti modi in Python):
Utilizzando le sezioni (ciò non comporta la rimozione dell'elemento dall'elenco originale):
(Anche questo sarà il metodo meno efficiente quando si lavora con l'elenco Python, ma questo potrebbe essere utile (ma non efficiente, lo ripeto) quando si lavora con oggetti definiti dall'utente che non supportano il pop, ma che definiscono 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]
Nota: questo metodo non modifica l'elenco in posizione come pop
e del
. Crea invece due copie di elenchi (uno dall'inizio fino all'indice ma senza di esso ( a[:index]
) e uno dopo l'indice fino all'ultimo elemento ( a[index+1:]
)) e crea un nuovo oggetto elenco aggiungendo entrambi. Questo viene quindi riassegnato alla variabile di elenco ( a
). Il vecchio oggetto elenco è quindi privo di riferimenti e quindi immondizia raccolta (a condizione che l'oggetto elenco originale non faccia riferimento a nessuna variabile diversa da a).
Questo rende questo metodo molto inefficiente e può anche produrre effetti collaterali indesiderati (specialmente quando altre variabili puntano all'oggetto elenco originale che rimane non modificato).
Grazie a @MarkDickinson per averlo segnalato ...
Questa risposta Stack Overflow spiega il concetto di slicing.
Si noti inoltre che questo funziona solo con indici positivi.
Durante l'utilizzo con gli oggetti, il __getitem__
metodo deve essere stato definito e, soprattutto, il __add__
metodo deve essere stato definito per restituire un oggetto contenente elementi da entrambi gli operandi.
In sostanza, questo funziona con qualsiasi oggetto la cui definizione di classe è simile a:
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 )
Funziona con il list
quale definisce __getitem__
e __add__
metodi.
Confronto dei tre modi in termini di efficienza:
Supponiamo che sia predefinito:
a = range(10)
index = 3
Il del object[index]
metodo:
Di gran lunga il metodo più efficiente. Funziona con tutti gli oggetti che definiscono un __del__
metodo.
Lo smontaggio è il seguente:
Codice:
def del_method():
global a
global index
del a[index]
Smontaggio:
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
metodo:
È meno efficiente del metodo del e viene utilizzato quando è necessario ottenere l'elemento eliminato.
Codice:
def pop_method():
global a
global index
a.pop(index)
Smontaggio:
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
Metodo slice e add.
Il meno efficiente.
Codice:
def slice_method():
global a
global index
a = a[:index] + a[index+1:]
Smontaggio:
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
Nota: in tutti e tre i disassemblaggi ignorare le ultime due righe che sostanzialmente lo sono return None
. Anche le prime due righe stanno caricando i valori globali a
e index
.
O(n)
in funzione tempo.deque()
fornisce operazioni efficienti su entrambe le estremità ma non fornisce O (1) inserimenti / ricerche / eliminazioni nel mezzo.