Warum haben Python-Diktate und -Sets eine clear () -Methode, aber keine Listen?
Job
13
Wenn jedoch mehrere Verweise auf das Objekt vorhanden sind, kann dies hilfreich sein.
Ned Deily
3
Dies kann hilfreich sein, wenn ich zur Laufzeit eine gemeinsam genutzte Liste über Prozesse hinweg löschen und nicht auf Garbaging warten muss (oder irre ich mich? Habe ich die Garbage Collection falsch verstanden?). Auch wenn ich jedes geknallte Element überprüfen möchte, kann ich es debuggen, während ich kein Slicing verwenden kann (oder irre ich mich). Ich muss die Prozessausführung nicht stoppen, während ich meine Liste lösche.
DrFalk3n
2
@ S.Lott Nur weil du nicht verstehst, warum das wichtig ist, heißt das nicht, dass der Rest von uns es nicht tut. Wenn mehrere Objekte von einer gemeinsamen Liste abhängen, ist dies von Bedeutung. In mehreren Entwurfsmustern ist dies wichtig. Garbage Collector bedeutet, dass Sie nicht nach sich selbst aufräumen müssen. Es ist keine Lizenz, mehr Chaos zu verursachen.
UpAndAdam
4
Ungeachtet anderer, besserer Antworten hätte Ihr ursprünglicher Code geschrieben werden können: while alist: alist.pop ()
MrWonderful
Antworten:
570
Dadurch wird der Inhalt tatsächlich aus der Liste entfernt, das alte Etikett wird jedoch nicht durch eine neue leere Liste ersetzt:
del lst[:]
Hier ist ein Beispiel:
lst1 =[1,2,3]
lst2 = lst1
del lst1[:]print(lst2)
Der Vollständigkeit halber hat die Slice-Zuordnung den gleichen Effekt:
lst[:]=[]
Es kann auch verwendet werden, um einen Teil der Liste zu verkleinern und gleichzeitig einen Teil zu ersetzen (dies liegt jedoch nicht im Rahmen der Frage).
Beachten Sie, dass dabei lst = []die Liste nicht geleert wird lst, sondern nur ein neues Objekt erstellt und an die Variable gebunden wird. Die alte Liste enthält jedoch weiterhin dieselben Elemente. Der Effekt wird sichtbar, wenn andere Variablenbindungen vorhanden sind.
Zwei weitere Fragen: Was genau ist "del"? (Ich schließe daraus, dass es Dinge löscht, aber ich weiß nicht wirklich, was es ist) und 2 .: Wie liest du (laut) [:]
Normalerweise lese ich keinen lauten Python-Code xD vor, aber wenn ich müsste, würde ich sagen "Slice vom Anfang bis zum Ende der Liste l".
Fortan
2
@jellybean völlig unbeabsichtigt ^ _ ^ Englisch ist nicht meine Muttersprache, daher habe ich den Kontrast zwischen den beiden Kommentaren wirklich nicht bemerkt.
Fortan
Wenn wir l = [] tun, wird der alte Listeninhalt dann nicht von Python GC gesammelt?
Alex Punnen
168
Wenn Sie Python 3.3 oder besser ausführen, können Sie die clear()Methode of list, die parallel zu clear()of dictist set, dequeund andere veränderbare Containertypen verwenden:
alist.clear()# removes all items from alist (equivalent to del alist[:])
Dasselbe kann laut der verlinkten Dokumentationsseite auch mit erreicht werden alist *= 0.
Zusammenfassend lässt sich sagen, dass es vier gleichwertige Möglichkeiten gibt, eine Liste an Ort und Stelle zu löschen (ganz im Gegensatz zum Zen von Python !):
@mitenka, das die Liste nicht leert, überschreibt die Variable alistmit einer anderen Liste, die zufällig leer ist. Wenn jemand anderes einen Verweis auf die ursprüngliche Liste hatte, bleibt dieser unverändert (dh er enthält alles, was darin enthalten war)
Adam Batkin
@mitenka Ein weiterer Grund ist, dass alist.clear()oder alist[:] = []hilft zu überprüfen, dass alistwirklich eine Liste ist. Angenommen, Sie wurden alistvon einer Funktion zurückgegeben foo(). Sie dachten, es würde fooeine Liste zurückgegeben, aber tatsächlich wurde eine zurückgegeben None. Mit alist = []kann diesen Fehler nicht abfangen.
aafulei
32
es stellt sich heraus, dass mit Python 2.5.2 del l[:]etwas langsamer ist als l[:] = []um 1.1 usec.
$ python -mtimeit "l=list(range(1000))""b=l[:];del b[:]"10000 loops, best of 3:29.8 usec per loop
$ python -mtimeit "l=list(range(1000))""b=l[:];b[:] = []"10000 loops, best of 3:28.7 usec per loop
$ python -V
Python2.5.2
In Python 2.7.2 sind sie auf meinem Computer ungefähr gleich. Sie laufen beide von 13,5 bis 13,7 usec pro Schleife.
leetNightshade
Sie sollten auch python3 -mtimeit "l = list (range (1000))" "b = l [:]" messen, um "b [:] = []" und "del b [:]" zu berechnen. Mach es und lol ...
Rockdaboot
1
Ich habe den Benchmark mit Python 3.5 durchgeführt und bin mit leetNightshade einverstanden. .clear(), del b[:]Und b[:]=[]alles läuft die gleiche ( b[:]=[]geringfügig langsamer.
Conchylicultor
5
lst *=0
hat den gleichen Effekt wie
lst[:]=[]
Es ist etwas einfacher und vielleicht leichter zu merken. Ansonsten gibt es nicht viel zu sagen
Der Vollständigkeit halber ist zu erwähnen, dass jede gegebene ganze Zahl, die kleiner oder gleich ist, 0den gleichen Effekt hat. Es ist ein ziemlich ordentlicher Trick, ich bin ein bisschen traurig, dass er nicht viel Aufmerksamkeit erhalten hat.
Peter Varo
-1
list =[]
wird listauf eine leere Liste zurückgesetzt.
Beachten Sie, dass Sie in der Regel nicht reservierte Funktionsnamen Schatten sollen, wie list, die der Konstruktor für eine Liste Objekt ist - könnten Sie lstoder list_stattdessen zum Beispiel.
Nein: Dadurch wird die Liste nicht geändert. Der Variablen wird lediglich eine leere Liste zugewiesen list. Wenn Sie erwartet hätten, dass eine Funktion eine übergebene Liste ändert (zum Beispiel), würde dies nicht das tun, was Sie wollen.
Adam Batkin
10
Nicht wirklich. Die Frage ist "Wie man eine Liste leert" und nicht "Wie man eine Variable
zuweist
6
Die Frage war nicht mehrdeutig, das Snippet der
Operation löschte
7
Außerdem sollte "Liste" nicht als Variablenname verwendet werden, da Schatten der Typ "Liste" sind. Viele Python-Entwickler verwenden "L" als Namen für Listenvariablen, aber ich bevorzuge "lst".
Steveha
1
Manchmal möchten Sie nur, dass die Liste geleert wird, und dies ist so gut wie jede der vorgeschlagenen Methoden. Wahrscheinlich noch schneller
smac89
-3
Ein weiterer einfacher Code, den Sie (abhängig von Ihrer Situation) verwenden können, ist:
Sie müssen den Index an der Länge der Liste beginnen und rückwärts gegenüber dem Index bei 0 vorwärts gehen, da dies dazu führen würde, dass der Index der Länge der Liste entspricht und nur halbiert wird.
Stellen Sie außerdem sicher, dass die while-Zeile ein Vorzeichen "größer oder gleich" hat. Wenn Sie es weglassen, bleibt die Liste [0] übrig.
Haha. Dies ist die zweite seltsame Antwort (+ ein entsprechender Kommentar), die mir auf SO begegnet ist. Es sollte eine Seite für diese denkwürdigen Dinge geben: D
Antworten:
Dadurch wird der Inhalt tatsächlich aus der Liste entfernt, das alte Etikett wird jedoch nicht durch eine neue leere Liste ersetzt:
Hier ist ein Beispiel:
Der Vollständigkeit halber hat die Slice-Zuordnung den gleichen Effekt:
Es kann auch verwendet werden, um einen Teil der Liste zu verkleinern und gleichzeitig einen Teil zu ersetzen (dies liegt jedoch nicht im Rahmen der Frage).
Beachten Sie, dass dabei
lst = []
die Liste nicht geleert wirdlst
, sondern nur ein neues Objekt erstellt und an die Variable gebunden wird. Die alte Liste enthält jedoch weiterhin dieselben Elemente. Der Effekt wird sichtbar, wenn andere Variablenbindungen vorhanden sind.quelle
Wenn Sie Python 3.3 oder besser ausführen, können Sie die
clear()
Methode oflist
, die parallel zuclear()
ofdict
istset
,deque
und andere veränderbare Containertypen verwenden:Dasselbe kann laut der verlinkten Dokumentationsseite auch mit erreicht werden
alist *= 0
.Zusammenfassend lässt sich sagen, dass es vier gleichwertige Möglichkeiten gibt, eine Liste an Ort und Stelle zu löschen (ganz im Gegensatz zum Zen von Python !):
alist.clear() # Python 3.3+
del alist[:]
alist[:] = []
alist *= 0
quelle
Du könntest es versuchen:
Was bedeutet: Spleißen Sie in der Liste
[]
(0 Elemente) an der Stelle[:]
(alle Indizes von Anfang bis Ende)Das [:] ist der Slice-Operator. Weitere Informationen finden Sie in dieser Frage .
quelle
alist = []
?alist
mit einer anderen Liste, die zufällig leer ist. Wenn jemand anderes einen Verweis auf die ursprüngliche Liste hatte, bleibt dieser unverändert (dh er enthält alles, was darin enthalten war)alist.clear()
oderalist[:] = []
hilft zu überprüfen, dassalist
wirklich eine Liste ist. Angenommen, Sie wurdenalist
von einer Funktion zurückgegebenfoo()
. Sie dachten, es würdefoo
eine Liste zurückgegeben, aber tatsächlich wurde eine zurückgegebenNone
. Mitalist = []
kann diesen Fehler nicht abfangen.es stellt sich heraus, dass mit Python 2.5.2
del l[:]
etwas langsamer ist alsl[:] = []
um 1.1 usec.quelle
.clear()
,del b[:]
Undb[:]=[]
alles läuft die gleiche (b[:]=[]
geringfügig langsamer.hat den gleichen Effekt wie
Es ist etwas einfacher und vielleicht leichter zu merken. Ansonsten gibt es nicht viel zu sagen
Die Effizienz scheint ungefähr gleich zu sein
quelle
0
den gleichen Effekt hat. Es ist ein ziemlich ordentlicher Trick, ich bin ein bisschen traurig, dass er nicht viel Aufmerksamkeit erhalten hat.wird
list
auf eine leere Liste zurückgesetzt.Beachten Sie, dass Sie in der Regel nicht reservierte Funktionsnamen Schatten sollen, wie
list
, die der Konstruktor für eine Liste Objekt ist - könnten Sielst
oderlist_
stattdessen zum Beispiel.quelle
list
. Wenn Sie erwartet hätten, dass eine Funktion eine übergebene Liste ändert (zum Beispiel), würde dies nicht das tun, was Sie wollen.Ein weiterer einfacher Code, den Sie (abhängig von Ihrer Situation) verwenden können, ist:
Sie müssen den Index an der Länge der Liste beginnen und rückwärts gegenüber dem Index bei 0 vorwärts gehen, da dies dazu führen würde, dass der Index der Länge der Liste entspricht und nur halbiert wird.
Stellen Sie außerdem sicher, dass die while-Zeile ein Vorzeichen "größer oder gleich" hat. Wenn Sie es weglassen, bleibt die Liste [0] übrig.
quelle