So entfernen Sie ein Element aus einer Liste nach Index

1505

Wie entferne ich ein Element aus einer Liste nach Index in Python?

Ich habe die list.removeMethode gefunden, möchte aber sagen, dass ich das letzte Element entfernen möchte. Wie mache ich das? Es scheint, als würde das Standard-Entfernen die Liste durchsuchen, aber ich möchte nicht, dass eine Suche durchgeführt wird.

Joan Venge
quelle
10
@smci: Python-Liste ist Array-basiert: Um ein Element in der Mitte zu löschen, müssen Sie alle Elemente auf der rechten Seite verschieben, um die Lücke zu entfernen, weshalb es sich O(n)im Zeitbetrieb befindet. deque()Bietet effiziente Operationen an beiden Enden, bietet jedoch keine O (1) Einfügungen / Suchvorgänge / Löschungen in der Mitte.
JFS
@JFSebastian: cPython-Implementierung, ja, danke, dass Sie mich korrigiert haben. Streng genommen gibt die Sprachspezifikation nicht an, wie die Liste implementiert werden soll. Alternative Implementierungen können eine verknüpfte Liste verwenden.
smci
@smci: keine praktische Umsetzung Python verwenden würde O(n)Indexzugriff a[i](durch verknüpfte Listen). Hinweis: Die Array-basierte Implementierung bietet O(1)Indexzugriff.
JFS
@JFSebastian: natürlich. Ich habe lediglich festgestellt, dass die Sprachspezifikation dies nicht definiert , sondern ein Implementierungsproblem darstellt. (Ich war überrascht, dass dies nicht der
Fall war
@smci Wenn Sie das allgemein ansprechen, bin ich mir nicht sicher, wie Sie hoffen können, etwas zu optimieren.
Nick T

Antworten:

1740

Verwenden delund geben Sie den Index des Elements an, das Sie löschen möchten:

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

Unterstützt auch Slices:

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

Hier ist der Abschnitt aus dem Tutorial.

Neil Chowdhury
quelle
53
Danke, was ist der Unterschied zwischen Pop und Del?
Joan Venge
37
del ist überladen. Zum Beispiel löscht del a die gesamte Liste
Brian R. Bondy
34
Ein weiteres Beispiel del a [2: 4] löscht die Elemente 2 und 3
Brian R. Bondy
307
pop () gibt das Element zurück, das Sie entfernen möchten. del nur löscht ist.
13
Ich kann dort keinen Beweis für eine "verknüpfte Liste" sehen. Sehen Sie sich unter svn.python.org/projects/python/trunk/Objects/listobject.c an, wie im PyList_GetItem()Wesentlichen ((PyListObject *)op) -> ob_item[i];das ith-Element eines Arrays zurückgegeben wird.
glglgl
649

Sie wollen wahrscheinlich pop:

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

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

Standardmäßig wird popohne Argumente das letzte Element entfernt:

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

# now a is ['a', 'b', 'c']
Jarret Hardie
quelle
105
Pop (-1) nicht vergessen. Ja, es ist die Standardeinstellung, aber ich bevorzuge sie, damit ich mich nicht daran erinnern muss, welches End-Pop standardmäßig verwendet wird.
S.Lott
282
Ich stimme dir nicht zu. Wenn Sie die Etymologie des Programmierers von "Pop" kennen (es ist die Operation, die den Anfang einer 'Stack'-Datenstruktur entfernt und zurückgibt ), dann ist dies pop()an sich sehr offensichtlich, während pop(-1)es gerade deshalb möglicherweise verwirrend ist, weil es redundant ist.
Coredumperror
a.pop (-1), um den letzten zu entfernen?
zx1986
14
@ zx1986 a entfernt popin den meisten Programmiersprachen normalerweise das letzte Element, wie dies in Python der Fall ist. Ob Sie also -1 oder nichts angeben, ist gleich.
Pascal
30
Gibt übrigens das pop()entfernte Element zurück.
Bob Stein
136

Wie bereits erwähnt, sind Pop und Del die effiziente Möglichkeit, ein Element eines bestimmten Index zu entfernen. Nur zur Vervollständigung (da dasselbe in Python auf viele Arten möglich ist):

Verwenden von Slices (dies führt nicht zum Entfernen des Elements aus der ursprünglichen Liste):

(Dies ist auch die am wenigsten effiziente Methode, wenn Sie mit Python-Listen arbeiten. Dies kann jedoch nützlich sein (aber nicht effizient, wie ich wiederhole), wenn Sie mit benutzerdefinierten Objekten arbeiten, die Pop nicht unterstützen, aber a definieren:) __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]

Hinweis: Bitte beachten Sie, dass diese Methode die Liste wie popund nicht ändert del. Stattdessen werden zwei Kopien von Listen erstellt (eine vom Anfang bis zum Index, jedoch ohne ( a[:index]) und eine nach dem Index bis zum letzten Element ( a[index+1:])) und ein neues Listenobjekt erstellt, indem beide hinzugefügt werden. Dies wird dann der Listenvariablen ( a) neu zugewiesen . Das alte Listenobjekt wird daher dereferenziert und somit Müll gesammelt (vorausgesetzt, das ursprüngliche Listenobjekt wird von keiner anderen Variablen als a referenziert).

Dies macht diese Methode sehr ineffizient und kann auch unerwünschte Nebenwirkungen hervorrufen (insbesondere wenn andere Variablen auf das ursprüngliche Listenobjekt verweisen, das unverändert bleibt).

Vielen Dank an @MarkDickinson für diesen Hinweis ...

Diese Antwort zum Stapelüberlauf erläutert das Konzept des Schneidens.

Beachten Sie auch, dass dies nur mit positiven Indizes funktioniert.

Bei der Verwendung mit Objekten muss die __getitem__Methode definiert worden sein, und was noch wichtiger ist, die __add__Methode muss definiert worden sein, um ein Objekt zurückzugeben, das Elemente aus beiden Operanden enthält.

Im Wesentlichen funktioniert dies mit jedem Objekt, dessen Klassendefinition wie folgt lautet:

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 )

Dies funktioniert mit listwelchen Definitionen __getitem__und __add__Methoden.

Vergleich der drei Möglichkeiten hinsichtlich der Effizienz:

Angenommen, Folgendes ist vordefiniert:

a = range(10)
index = 3

Die del object[index]Methode:

Mit Abstand die effizienteste Methode. Es funktioniert mit allen Objekten, die eine __del__Methode definieren .

Die Demontage ist wie folgt:

Code:

def del_method():
    global a
    global index
    del a[index]

Demontage:

 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 Methode:

Es ist weniger effizient als die del-Methode und wird verwendet, wenn Sie das gelöschte Element abrufen müssen.

Code:

def pop_method():
    global a
    global index
    a.pop(index)

Demontage:

 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

Die Slice-and-Add-Methode.

Am wenigsten effizient.

Code:

def slice_method():
    global a
    global index
    a = a[:index] + a[index+1:]

Demontage:

 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

Hinweis: Ignorieren Sie bei allen drei Demontagen die letzten beiden Zeilen, die im Grunde genommen sind return None. Auch die ersten beiden Zeilen laden die globalen Werte aund index.

Raghav RV
quelle
4
Ihre Slicing-Methode entfernt kein Element aus einer Liste. Stattdessen wird ein neues Listenobjekt erstellt, das alle bis auf den i-ten Eintrag aus der ursprünglichen Liste enthält. Die ursprüngliche Liste bleibt unverändert.
Mark Dickinson
@ MarkDickinson Haben Sie die Antwort bearbeitet, um dasselbe zu klären ... Bitte lassen Sie mich wissen, ob es jetzt gut aussieht?
Raghav RV
6
Vielleicht war die Antwort nicht ganz thematisch, aber die Indizierungsmethode ist nützlich, wenn Sie ein Element aus einem unveränderlichen Objekt wie einem Tupel weglassen müssen. pop () und del () funktionieren in diesem Fall nicht.
Caleb
6
@ rvraghav93 Von allen vorgestellten Methoden während des gesamten Beitrags war der a = a[:index] + a[index+1 :]-trick der sicherste, wenn es um riesige Listen geht. Alle anderen Methoden endeten in einem Deadlock. Also vielen Dank
user3085931
3
In der Tat, Mark, du bist mürrisch. Diese Antwort habe ich bevorzugt, weil sie wirklich pädagogisch war. Ich habe am meisten aus dieser Antwort und den bereitgestellten Details zur Demontage und den Auswirkungen auf die Leistung gelernt. Plus die Slicing-Methode, ja, erstellen Sie ein anderes Objekt, aber jetzt ist es angegeben und manchmal ist das auch das, was Sie brauchen.
Yohan Obadia
52

popist auch nützlich, um ein Element zu entfernen und aus einer Liste zu behalten. Wo delder Gegenstand tatsächlich weggeworfen wird.

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

>>> p = x.pop(1)
>>> p
    2
Bootscodierer
quelle
24

Wenn Sie das bestimmte Positionselement in einer Liste entfernen möchten, z. B. das 2., 3. und 7 .. du kannst nicht benutzen

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

Da nach dem Löschen des zweiten Elements das dritte Element, das Sie löschen, tatsächlich das vierte Element in der ursprünglichen Liste ist. Sie können das 2., 3. und 7. Element in der ursprünglichen Liste filtern und eine neue Liste erhalten, wie unten:

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

Dies hängt davon ab, was Sie tun möchten.

Wenn Sie das entfernte Element zurückgeben möchten, verwenden Sie pop():

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

Wenn Sie jedoch nur ein Element löschen möchten, verwenden Sie del:

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

Außerdem delkönnen Sie Slices verwenden (z del[2:]. B. ).

Neil Chowdhury
quelle
18

Im Allgemeinen verwende ich die folgende Methode:

>>> myList = [10,20,30,40,50]
>>> rmovIndxNo = 3
>>> del myList[rmovIndxNo]
>>> myList
[10, 20, 30, 50]
Mayur Koshti
quelle
15

Eine weitere Möglichkeit, ein oder mehrere Elemente nach Index aus einer Liste zu entfernen.

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] zeigt auf die Elemente von Index xbis y-1. Wenn wir diesen Teil der Liste als leere Liste deklarieren ( []), werden diese Elemente entfernt.

Andreas Chatzivasileiadis
quelle
14

Sie können einfach nach dem Element suchen, das Sie löschen möchten. Es ist wirklich einfach. Beispiel:

    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)

Ausgabe: acde

SollyBunny
quelle
6
Ich mag diese Lösung, aber es wird natürlich davon ausgegangen, dass Ihre Liste keine Duplikate enthält.
Tommy.carstensen
11

Verwenden Sie den folgenden Code, um das Element aus der Liste zu entfernen:

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

output = [2, 3, 4]

Wenn Sie Indexelementdaten aus der Liste entfernen möchten, verwenden Sie:

list = [1, 2, 3, 4]
list.remove(list[2])
print(list)
output : [1, 2, 4]
jitsm555
quelle
2
Kommt mit der Einschränkung, dass Ihre Liste keine Duplikate enthalten kann.
Tommy.carstensen
3
Dies erfolgt nicht nach Index, sondern nach übereinstimmendem Wert. Das mag für einige Besucher wertvolle Informationen sein, versucht aber überhaupt nicht, die Frage des OP zu beantworten.
Anthon
8

Wie bereits erwähnt, ist die beste Vorgehensweise del (). oder pop (), wenn Sie den Wert kennen müssen.

Eine alternative Lösung besteht darin, nur die gewünschten Elemente neu zu stapeln:

    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 ... funktioniert nicht bei negativen Indexwerten, denkt nach und aktualisiert

Schätze ich

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

würde es flicken ... aber plötzlich scheint diese Idee sehr spröde. Interessantes Gedankenexperiment. Es scheint, dass es einen "richtigen" Weg geben sollte, dies mit dem Verständnis von append () / list zu tun.

Nachdenken

Präsenz
quelle
1
Welche Version von Python hat eine Funktion del()? Für diese Funktion geben Sie die Liste als erstes Argument für diese Funktion an und dann den Index oder zuerst den Index und dann die Liste? Gibt es das Listenargument ohne das Element zurück oder löscht es an Ort und Stelle. Ich kenne die delAnweisung, aber nicht eine Funktion mit demselben Namen.
Anthon
8

Es hört sich nicht so an, als würden Sie mit einer Liste von Listen arbeiten, also werde ich mich kurz fassen. Sie möchten Pop verwenden, da dadurch Elemente entfernt werden, die keine Listen sind. Verwenden Sie dazu del. Um das letzte Element in Python aufzurufen, ist es "-1".

>>> test = ['item1', 'item2']
>>> test.pop(-1)
'item2'
>>> test
['item1']
Mo Ali
quelle
1
pop()und delbeide entfernen ein Element am bereitgestellten Index, unabhängig davon, ob dieses Element selbst eine Liste ist oder nicht. a = [1, [2, 3], 4]; del a[1]; b = [1, [2, 3], 4]; b.pop(1); assert a == b
Anthon
8

l - Werteliste; Wir müssen Indizes aus der inds2rem- Liste entfernen .

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]
Jo Ja
quelle
funktioniert nicht, die Antwort ist <map at 0x7f4d54109a58>. und l ist Bereich (0,20)
Hitesh
7

Verwenden Sie die Funktion "del" :

del listName[-N]

Wenn Sie beispielsweise die letzten drei Elemente entfernen möchten, sollte Ihr Code wie folgt lauten:

del listName[-3:]

Wenn Sie beispielsweise die letzten 8 Elemente entfernen möchten, sollte Ihr Code wie folgt lauten:

del listName[-8:]
lloydyu24
quelle
2
delist eine Aussage . Wenn es eine Funktion wäre, müssten Sie schreibendel(listame[-N])
Anthon
7

Es wurde bereits erwähnt, wie ein einzelnes Element aus einer Liste entfernt werden kann und welche Vorteile die verschiedenen Methoden haben. Beachten Sie jedoch, dass das Entfernen mehrerer Elemente zu Fehlern führen kann:

>>> 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]

Die Elemente 3 und 8 (nicht 3 und 7) der ursprünglichen Liste wurden entfernt (da die Liste während der Schleife gekürzt wurde), was möglicherweise nicht beabsichtigt war. Wenn Sie mehrere Indizes sicher entfernen möchten, sollten Sie stattdessen zuerst die Elemente mit dem höchsten Index löschen, z. B.:

>>> 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]
Kopfgeldjäger
quelle
4

Oder wenn mehrere Indizes entfernt werden sollen:

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

Natürlich könnte man dann auch:

print([v for i,v in enumerate(your_list) if i != unwanted_index])
U10-Vorwärts
quelle
1
Warum sortieren Sie die Liste der Indizes nicht einfach in umgekehrter Reihenfolge und löschen sie dann nacheinander? Auf diese Weise müssen Sie keine neue Liste erstellen.
Anthon
3

Sie können entweder del oder pop verwenden, um Elemente basierend auf dem Index aus der Liste zu entfernen. Pop druckt das Mitglied, das aus der Liste entfernt wird, während die Liste dieses Mitglied löscht, ohne es zu drucken.

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

Man kann entweder del oder pop verwenden, aber ich bevorzuge del, da Sie Index und Slices angeben können, um dem Benutzer mehr Kontrolle über die Daten zu geben.

Beginnend mit der angezeigten Liste kann man beispielsweise das letzte Element mit delals Slice entfernen und dann das letzte Element mit aus dem Ergebnis entfernen pop.

>>> l = [1,2,3,4,5]
>>> del l[-1:]
>>> l
[1, 2, 3, 4]
>>> l.pop(-1)
4
>>> l
[1, 2, 3]
Pyman
quelle