35 Stimmen

Warum geben diese Listenoperationen (Methoden: clear / extend / reverse / append / sort / remove) None zurück und nicht die resultierende Liste?

Ich habe festgestellt, dass viele Operationen auf Listen, die den Inhalt der Liste ändern, Folgendes zurückgeben None anstatt die Liste selbst zurückzugeben. Beispiele:

>>> mylist = ['a', 'b', 'c']
>>> empty = mylist.clear()
>>> restored = mylist.extend(range(3))
>>> backwards = mylist.reverse()
>>> with_four = mylist.append(4)
>>> in_order = mylist.sort()
>>> without_one = mylist.remove(1)
>>> mylist
[0, 2, 4]
>>> [empty, restored, backwards, with_four, in_order, without_one]
[None, None, None, None, None, None]

Welche Überlegungen stehen hinter dieser Entscheidung?

Mir scheint dies hinderlich zu sein, da es die "Verkettung" der Listenverarbeitung verhindert (z.B. mylist.reverse().append('a string')[:someLimit] ). Ich könnte mir vorstellen, dass "die Mächtigen" entschieden haben, dass das Listenverständnis das bessere Paradigma ist (eine berechtigte Meinung), und deshalb andere Methoden nicht fördern wollten - aber es scheint pervers, eine intuitive Methode zu verhindern, selbst wenn es bessere Alternativen gibt.


Diese Frage bezieht sich speziell auf Pythons <em>Entwurfsentscheidung </em>zur Rückkehr <code>None</code> von mutierenden Listenmethoden wie <code>.append</code> . Anfänger schreiben oft falschen Code, der erwartet <code>.append</code> (insbesondere), um die gleiche Liste zurückzugeben, die gerade geändert wurde.

Für die einfache Frage nach " <strong>wie </strong>an eine Liste anhängen?" (oder Fragen zur Fehlersuche, die auf dieses Problem hinauslaufen), siehe <a href="https://stackoverflow.com/questions/6339235">Warum funktioniert "x = x.append([i])" nicht in einer for-Schleife? </a>.

Um geänderte Versionen der Liste zu erhalten, siehe:

Das gleiche Problem gilt für einige Methoden anderer eingebauter Datentypen, z. B. <code>set.discard</code> (siehe <a href="https://stackoverflow.com/questions/22877032">Wie entfernt man ein bestimmtes Element aus einer Menge innerhalb einer Liste mit Hilfe des Listenverständnisses? </a>) und <code>dict.update</code> (siehe <a href="https://stackoverflow.com/questions/1452995/">Warum gibt ein python dict.update() das Objekt nicht zurück? </a>).

Die gleichen Überlegungen gelten für die Entwicklung eigener APIs. Siehe <a href="https://stackoverflow.com/questions/13062423">Ist es eine schlechte Idee, wenn In-Place-Operationen das Objekt zurückgeben? </a>.

-1voto

Mehdi Hamzezadeh Punkte 370

Zunächst einmal sollte ich sagen, dass das, was ich vorschlage, ohne Zweifel eine schlechte Programmierpraxis ist, aber wenn Sie append in Lambda-Funktion verwenden möchten und die Lesbarkeit des Codes ist Ihnen egal gibt es eine Möglichkeit, genau das zu tun.

Stellen Sie sich vor, Sie haben eine Liste von Listen und möchten an jede innere Liste ein Element anhängen, indem Sie map y lambda . hier ist, wie Sie das tun können:

my_list = [[1, 2, 3, 4],
           [3, 2, 1],
           [1, 1, 1]]
my_new_element = 10
new_list = list(map(lambda x: [x.append(my_new_element), x][1], my_list))

print(new_list)

Wie es funktioniert:

wenn lambda ausgeben möchte, sollte es zunächst die [x.append(my_new_element), x] Ausdruck. Zur Berechnung dieses Ausdrucks wird die append Funktion wird ausgeführt und das Ergebnis des Ausdrucks ist [None, x] und indem man angibt, dass das zweite Element der Liste das Ergebnis von [None,x][1] será x

Die Verwendung einer benutzerdefinierten Funktion ist besser lesbar und die bessere Option:

def append_my_list(input_list, new_element):
    input_list.append(new_element)
    return input_list

my_list = [[1, 2, 3, 4],
           [3, 2, 1],
           [1, 1, 1]]
my_new_element = 10
new_list = list(map(lambda x: append_my_list(x, my_new_element), my_list))

print(new_list)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X