Come rimuovere un elemento da un elenco per indice


1507

Come rimuovo un elemento da un elenco per indice in Python?

Ho trovato il list.removemetodo, ma dire che voglio rimuovere l'ultimo elemento, come posso fare? Sembra che la rimozione predefinita cerchi nella lista, ma non voglio che venga eseguita alcuna ricerca.


10
@smci: l'elenco Python è basato su array: per eliminare un elemento nel mezzo, è necessario spostare tutti gli elementi a destra per rimuovere il gap, motivo per cui è O(n)in funzione tempo. deque()fornisce operazioni efficienti su entrambe le estremità ma non fornisce O (1) inserimenti / ricerche / eliminazioni nel mezzo.
jfs,

@JFSebastian: implementazione di cPython, sì, grazie per avermi corretto. A rigor di termini le specifiche del linguaggio non specificano come implementare un elenco, implementazioni alternative potrebbero scegliere di utilizzare un elenco collegato.
smci,

@smci: nessuna implementazione pratica di Python userebbe l' O(n)accesso all'indice a[i](a causa di liste collegate). Nota: l'implementazione basata su array fornisce l' O(1)accesso all'indice.
jfs,

@JFSebastian: ovviamente. Ho semplicemente notato che le specifiche del linguaggio non lo definiscono , è un problema di implementazione. (Sono stato sorpreso di scoprire che non è così.)
smci

@smci se lo stai prendendo di mira in senso lato, non sono sicuro di come puoi sperare di ottimizzare qualcosa.
Nick T

Risposte:


1741

Utilizzare dele specificare l'indice dell'elemento che si desidera eliminare:

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[-1]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]

Supporta anche sezioni:

>>> del a[2:4]
>>> a
[0, 1, 4, 5, 6, 7, 8, 9]

Ecco la sezione del tutorial.


53
Grazie, qual è la differenza tra pop e del?
Joan Venge,

37
del è sovraccarico. Ad esempio, elimina l'intera lista
Brian R. Bondy,

34
un altro esempio di un [2: 4], elimina gli elementi 2 e 3
Brian R. Bondy

307
pop () restituisce l'elemento che si desidera rimuovere. del solo elimina è.

13
Non riesco a vedere una prova di "elenco collegato" lì. Guarda svn.python.org/projects/python/trunk/Objects/listobject.c come PyList_GetItem()essenzialmente ritorna ((PyListObject *)op) -> ob_item[i];- l' ielemento th di un array.
glglgl

649

Probabilmente vuoi pop:

a = ['a', 'b', 'c', 'd']
a.pop(1)

# now a is ['a', 'c', 'd']

Per impostazione predefinita, popsenza alcun argomento rimuove l'ultimo elemento:

a = ['a', 'b', 'c', 'd']
a.pop()

# now a is ['a', 'b', 'c']

105
Non dimenticare pop (-1). Sì, è l'impostazione predefinita, ma la preferisco, quindi non devo ricordare quale end pop utilizza per impostazione predefinita.
S.Lott

282
Non sono d'accordo. Se conosci l'etimologia del "pop" del programmatore (è l'operazione che rimuove e restituisce la parte superiore di una struttura di dati "stack"), allora di pop()per sé è molto ovvio, mentre pop(-1)è potenzialmente confuso proprio perché è ridondante.
coredumperror,

a.pop (-1) per rimuovere l'ultimo?
zx1986,

14
@ zx1986 a popnella maggior parte dei linguaggi di programmazione di solito rimuove l'ultimo elemento, come accade in Python. Quindi, se si specifica -1 o niente è lo stesso.
Pascal,

30
A proposito, pop()restituisce qualsiasi elemento rimosso.
Bob Stein,

136

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 pope 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 listquale 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 ae index.


4
Il tuo metodo slicing non rimuove un elemento da un elenco: crea invece un nuovo oggetto elenco contenente tutti tranne la voce dall'elenco originale. L'elenco originale non viene modificato.
Mark Dickinson,

@MarkDickinson Hai modificato la risposta per chiarire lo stesso ... Per favore fatemi sapere se sembra buono ora?
Raghav RV,

6
Forse la risposta non era interamente sull'argomento, ma il metodo di indicizzazione è utile se è necessario omettere un elemento da un oggetto immutabile, come una tupla. pop () e del () non funzioneranno in quel caso.
Caleb,

6
@ rvraghav93 di tutti i metodi presentati durante l'intero post, il a = a[:index] + a[index+1 :]trucco è stato il più sicuro, quando si tratta di liste enormi. Tutti gli altri metodi sono finiti in un punto morto. Quindi grazie mille
user3085931

3
Anzi, Mark, sei scontroso. Questa risposta è quella che preferivo perché era davvero pedagogica. Ho imparato di più da questa risposta e dai dettagli sul disassemblaggio forniti e sull'impatto sulla performance. Inoltre il metodo slicing, sì, crea un altro oggetto, ma ora è specificato e talvolta è anche quello che ti serve.
Yohan Obadia,

52

popè anche utile per rimuovere e mantenere un elemento da un elenco. Dove deleffettivamente trasporta l'oggetto.

>>> x = [1, 2, 3, 4]

>>> p = x.pop(1)
>>> p
    2

24

Se si desidera rimuovere l'elemento di posizione specifico in un elenco, come il 2o, 3o e 7o. non puoi usare

del my_list[2]
del my_list[3]
del my_list[7]

Dal momento che dopo aver eliminato il secondo elemento, il terzo elemento che elimini in realtà è il quarto elemento nell'elenco originale. Puoi filtrare il 2o, 3o e 7o elemento nell'elenco originale e ottenere un nuovo elenco, come di seguito:

new list = [j for i, j in enumerate(my_list) if i not in [2, 3, 7]]

19

Questo dipende da cosa vuoi fare.

Se si desidera restituire l'elemento rimosso, utilizzare pop():

>>> l = [1, 2, 3, 4, 5]
>>> l.pop(2)
3
>>> l
[1, 2, 4, 5]

Tuttavia, se vuoi solo eliminare un elemento, usa del:

>>> l = [1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]

Inoltre, delconsente di utilizzare le sezioni (ad es del[2:].).


18

In generale, sto usando il seguente metodo:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]

15

Ancora un altro modo per rimuovere un elemento (s) da un elenco per indice.

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# remove the element at index 3
a[3:4] = []
# a is now [0, 1, 2, 4, 5, 6, 7, 8, 9]

# remove the elements from index 3 to index 6
a[3:7] = []
# a is now [0, 1, 2, 7, 8, 9]

a [x: y] punta agli elementi dall'indice xa y-1. Quando dichiariamo quella parte dell'elenco come un elenco vuoto ( []), tali elementi vengono rimossi.


14

Potresti semplicemente cercare l'elemento che desideri eliminare. È davvero semplice Esempio:

    letters = ["a", "b", "c", "d", "e"]
    letters.remove(letters[1])
    print(*letters) # Used with a * to make it unpack you don't have to (Python 3.x or newer)

Uscita: acde


6
Mi piace questa soluzione, ma ovviamente presume che il tuo elenco non abbia duplicati.
tommy.carstensen,

11

Utilizzare il seguente codice per rimuovere l'elemento dall'elenco:

list = [1, 2, 3, 4]
list.remove(1)
print(list)

output = [2, 3, 4]

Se si desidera rimuovere i dati degli elementi di indice dall'elenco utilizzare:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]

2
Viene fornito l'avvertenza che l'elenco non può contenere duplicati.
tommy.carstensen,

3
Non viene rimosso per indice, ma per valore corrispondente. Potrebbe essere un'informazione preziosa per alcune persone che visitano qui, ma non prova a rispondere alla domanda dei PO.
Anthon,

8

Come accennato in precedenza, la migliore pratica è del (); o pop () se è necessario conoscere il valore.

Una soluzione alternativa è quella di ri-impilare solo gli elementi desiderati:

    a = ['a', 'b', 'c', 'd'] 

    def remove_element(list_,index_):
        clipboard = []
        for i in range(len(list_)):
            if i is not index_:
                clipboard.append(list_[i])
        return clipboard

    print(remove_element(a,2))

    >> ['a', 'b', 'd']

eta: hmm ... non funzionerà con valori di indice negativi, rifletterà e aggiornerà

Credo

if index_<0:index_=len(list_)+index_

lo rattopperei ... ma all'improvviso questa idea sembra molto fragile. Interessante esperimento mentale però. Sembra che ci dovrebbe essere un modo "corretto" per farlo con la comprensione append () / list.

riflettere


1
Quale versione di Python ha una funzione del()? Per quella funzione fornisci la lista come primo argomento di quella funzione e poi l'indice, o prima l'indice e poi la lista? Restituisce l'argomento elenco senza l'elemento o esegue l'eliminazione in atto. Conosco l' delistruzione, ma non una funzione con lo stesso nome.
Anthon,

8

Non sembra che tu stia lavorando con un elenco di elenchi, quindi lo terrò breve. Vuoi usare pop poiché rimuoverà elementi e non elementi che sono elenchi, per questo dovresti usare del. Per chiamare l'ultimo elemento in Python è "-1"

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']

1
pop()ed delentrambi rimuovono un elemento dall'indice fornito, indipendentemente dal fatto che quell'elemento sia o meno un elenco. a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Anthon,

8

l - elenco di valori; dobbiamo rimuovere gli indici dall'elenco inds2rem .

l = range(20)
inds2rem = [2,5,1,7]
map(lambda x: l.pop(x), sorted(inds2rem, key = lambda x:-x))

>>> l
[0, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

non funziona, la risposta è <map at 0x7f4d54109a58>. ed è range (0,20)
Hitesh

7

Utilizzare la funzione "del" :

del listName[-N]

Ad esempio, se si desidera rimuovere gli ultimi 3 elementi, il codice dovrebbe essere:

del listName[-3:]

Ad esempio, se si desidera rimuovere gli ultimi 8 elementi, il codice dovrebbe essere:

del listName[-8:]

2
delè una dichiarazione . Se fosse una funzione, dovresti scriveredel(listame[-N])
Anthon,

7

È già stato menzionato come rimuovere un singolo elemento da un elenco e quali vantaggi hanno i diversi metodi. Si noti, tuttavia, che la rimozione di più elementi ha alcuni potenziali errori:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in indices:
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 7, 9]

Gli elementi 3 e 8 (non 3 e 7) dell'elenco originale sono stati rimossi (poiché l'elenco è stato abbreviato durante il ciclo), che potrebbe non essere stata l'intenzione. Se desideri rimuovere in sicurezza più indici, devi prima eliminare prima gli elementi con l'indice più alto, ad esempio in questo modo:

>>> l = [0,1,2,3,4,5,6,7,8,9]
>>> indices=[3,7]
>>> for i in sorted(indices, reverse=True):
...     del l[i]
... 
>>> l
[0, 1, 2, 4, 5, 6, 8, 9]

4

O se è necessario rimuovere più indici:

print([v for i,v in enumerate(your_list) if i not in list_of_unwanted_indexes])

Ovviamente quindi potrebbe anche fare:

print([v for i,v in enumerate(your_list) if i != unwanted_index])

1
Perché non ordinare semplicemente l'elenco degli indici in ordine inverso e quindi eliminarli uno per uno? In questo modo non è necessario creare un nuovo elenco.
Anthon,

3

È possibile utilizzare del o pop per rimuovere l'elemento dall'elenco in base all'indice. Pop stamperà il membro che sta rimuovendo dall'elenco, mentre l'elenco elimina quel membro senza stamparlo.

>>> a=[1,2,3,4,5]
>>> del a[1]
>>> a
[1, 3, 4, 5]
>>> a.pop(1)
 3
>>> a
[1, 4, 5]
>>> 

3

Si può usare del o pop, ma io preferisco del, dal momento che è possibile specificare indice e sezioni, dando all'utente un maggiore controllo sui dati.

Ad esempio, a partire dall'elenco visualizzato, è possibile rimuovere l'ultimo elemento con delcome una sezione, quindi è possibile rimuovere l'ultimo elemento dal risultato utilizzando pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.