2009-09-09 7 views
37

von this question.Warum gibt es keine list.clear() Methode in Python?

Inspiriert Warum gibt es keine list.clear() Methode in Python? Ich habe hier einige Fragen gefunden, die sagen, dass der richtige Weg, dies zu tun, einer der folgenden ist, aber niemand hat gesagt, warum es nicht nur eine Methode dafür gibt.

del lst[:] 
lst[:] = [] 

Während es gegen das „zen von Python“ gehen kann mehr als ein Weg, etwas zu tun haben, so scheint es sicherlich noch deutlicher mir eine „list.clear()“ haben Methode. Es würde auch in Übereinstimmung mit Dicts und Sets fallen, die beide .clear() haben.

Ich stieß auf ein paar Posts zu den Python-Dev und Python-Ideen dazu und kam zu keiner endgültigen Antwort (siehe here (2006) und here (2009)). Hat Guido darauf geachtet? Ist das nur ein Streitpunkt, der in den letzten 4-5 Jahren noch nicht gelöst wurde?

Update: list.clear() wurde in 3,3 bis Python hinzugefügt - see here

+20

Das ist lächerlich, natürlich ist es ein Wert zu wissen, warum. Es gibt Einblicke in die Gestaltung der Sprache und ein tieferes Verständnis von Python. Für eine Sprache, die so benutzerfreundlich und intuitiv ist wie Python, war ich überrascht, dass sie nicht da war. Wenn es einen guten Grund gab, konnte ich mir keinen von ganz oben vorstellen. – job

Antwort

18

In den Gewinden Sie Raymond Hettinger pretty much sums up the pros and cons des Hinzufügens dieser Methode verknüpft. Wenn es um Sprachdesign geht, ist es sehr wichtig, konservativ zu sein. Siehe zum Beispiel das "every feature starts with -100 points" Prinzip das C# Team hat. Sie erhalten nicht etwas so sauberes wie Python, indem Sie Funktionen wie Nilly hinzufügen. Werfen Sie einen Blick auf einige der beliebtesten Skriptsprachen, um zu sehen, wo Sie hinkommen.

Ich denke, die .clear() Methode hat nie die implizite -100-Punkte-Regel überschritten, um etwas zu werden, das es wert ist, zur Kernsprache hinzugefügt zu werden. Obwohl der Methodenname bereits für einen gleichwertigen Zweck verwendet wird und die Alternative schwer zu finden ist, ist sie wahrscheinlich nicht so weit davon entfernt.

+0

+1: Es gibt keinen vernünftigen Anwendungsfall zum Löschen einer Liste, wenn die Garbage Collection funktioniert. –

+18

Beachten Sie, dass dies nun die Regel "-100 Punkte" überschritten hat und "list.clear()" in Python 3.3 hinzugefügt wurde - siehe [@ Jaceks Antwort] (http://stackoverflow.com/a/6675045/68707)). –

+1

@ S.Lott Wie wäre es, wenn Sie eine Unterklasse "Liste" haben, die eine Hilfsmethode hat (sagen wir aus einer Datenbank laden), die alle Elemente entfernen muss? – Tom

7

Ich kann das Warum nicht beantworten; aber da sollte es unbedingt einen geben, damit verschiedene Objekttypen mit der gleichen Schnittstelle gelöscht werden können.

Ein offensichtliches, einfaches Beispiel:

def process_and_clear_requests(reqs): 
    for r in reqs: 
     do_req(r) 
    reqs.clear() 

Dies erfordert lediglich, dass der Objektträger Iteration, und dass es klar unterstützen(). Wenn Listen eine clear() -Methode hatten, könnte dies eine Liste annehmen oder gleich setzen. Da Sets und Listen eine andere API zum Löschen ihrer Inhalte haben, funktioniert das nicht. Sie enden mit einem unnötig hässlich zerhacken, wie:

def process_and_clear_requests(reqs): 
    for r in reqs: 
     do_req(r) 
    if getattr(reqs, "clear"): 
     reqs.clear() 
    else: 
     del reqs[:] 

Was mich betrifft, del obj mit [:] oder obj [:] = [] sind nur unangenehm, unintuitive Hacks um die Arbeit Tatsache, dass die Liste fehlt().

Dies ist "Reduzierung der Redundanz" zu einem Fehler, wo es die Konsistenz der Sprache beschädigt, die noch wichtiger ist.

Was Sie verwenden sollten, würde ich del obj [:] empfehlen. Ich denke, es ist einfacher für nicht listenähnliche Objekte zu implementieren.

+0

Gute Punkte über konsistente Schnittstellen. Ich würde vorschlagen, dass Sie pop() in Ihrem Beispiel verwenden (ich weiß, dass es nur ein Beispiel ist), aber "pop()" dient nur dazu, Interfaceinkonsistenz hervorzuheben! – mhawke

+0

Ich hatte diese Anmerkung der Kürze wegen entfernt, aber: "add" und "append" der Liste sollten aus ähnlichen Gründen denselben Namen haben. Naja; Alle Sprachen haben ihre Warzen. –

14

Während es keine list.clear() gab, als diese Frage gestellt wurde, hat 3.3 jetzt einen (wie in http://bugs.python.org/issue10516 angefordert). Zusätzlich wurden clear() Methoden zu bytearray und MutableSequence hinzugefügt, um den Wechsel zwischen Listen und anderen Sammlungen (Set, Diktat usw.) zu erleichtern.

Vollständige Details der Änderung finden Sie here.

-9

Die Frage sollte sein, warum clear in erster Linie notwendig war. Das Folgende funktioniert, um jede Python-Sammlung zu löschen, die mir einfällt.

def clear(x): 
    return type(x)() 

>>> s = {1, 2, 3} 
>>> s 
set([1, 2, 3]) 
>>> s = clear(s) 
>>> s 
set([]) 
>>> l = [1, 2, 3] 
>>> l 
[1, 2, 3] 
>>> l = clear(l) 
>>> l 
[] 
+3

Das löscht ein Objekt nicht - es erstellt ein neues Objekt des entsprechenden Typs, das leer ist. Das ursprüngliche Objekt ist immer noch voll, und alle darin enthaltenen Referenzen sind noch aktiv. Oder fehlt mir etwas Offensichtliches? – DSM

+0

@DSM, OK Ich gebe zu, dass dies nicht in allen Fällen funktioniert, zum Beispiel wenn das Objekt an eine Funktion übergeben wurde und Sie versuchen, das Original zu verändern. Abgesehen davon sollte alles, was enthalten ist, weggehen, wenn der ursprüngliche Container Müll gesammelt wird. –

+2

Diese Methode sollte besser "neu" statt "klar" heißen. – MrWonderful

0

Beim Testen ist es oft sinnvoll, die Daten zur Einrichtung der Domäne der Tests in globalen Variablen bilden, so dass Tests aufeinander aufbauen können bei Bedarf/einfacher. In solchen Fällen können Sie mit einer Methode zum Löschen der Liste das tun, ohne diese Variablen innerhalb einer Funktion (d. H. Den Tests) als global deklarieren zu müssen. Ich weiß, die Tests sollten nicht voneinander abhängen ...

Verwandte Themen