Warum gibt "return list.sort ()" None zurück, nicht die Liste?

153

Ich konnte überprüfen, ob findUniqueWordsdies zu einer Sortierung führt list. Die Liste wird jedoch nicht zurückgegeben. Warum?

def findUniqueWords(theList):
    newList = []
    words = []

    # Read a line at a time
    for item in theList:

        # Remove any punctuation from the line
        cleaned = cleanUp(item)

        # Split the line into separate words
        words = cleaned.split()

        # Evaluate each word
        for word in words:

            # Count each unique word
            if word not in newList:
                newList.append(word)

    answer = newList.sort()
    return answer
Lee_Str
quelle
Ich glaube nicht, dass Sie einen Gegenstand so oft in einen String verwandeln müssen. Einmal ist normalerweise genug und es ist sauberer, es auch am Eingang zu cleanUp zu tun.
Ben
3
Nur ein dummer Gedanke, aber wenn Sie eine Liste einzigartiger Gegenstände wollen, warum konvertieren Sie sie nicht einfach in ein Set? Sie können sie dann bei Bedarf wieder in eine Liste konvertieren. theSet= set(theList) Und wenn Sie fertig sind, müssen Sie es nur noch auf die Liste theList = list(theSet) zurücksetzen : Fertig. Einfach.
runlevel0
1
Hinzufügen zu dem, was @ runlevel0 gesagt hat (was eine gute Idee ist): Sie können ein theSet' into a sorted list with sortiertes (theSet) ` konvertieren .
Zaz
sehr unregelmäßige Sprache
Nicole
Dies ist eine zentrale - aber problematische / irritierende - philosophische Wahl der Sprache. Verkettung im Allgemeinen ist ein verwaistes Konzept in Python.
Javadba

Antworten:

193

list.sortsortiert die Liste an Ort und Stelle, dh es wird keine neue Liste zurückgegeben. Einfach schreiben

newList.sort()
return newList
Ismail Badawi
quelle
18
return sorted(newList)ist kürzer. Dies spielt hier keine Rolle, da die Variable lokal ist, aber die direkte Sortierung kann in einigen Fällen eine gemeinsam genutzte Variable ändern.
Jean-François Fabre
Es ist interessant, dass wenn ein Eintrag zu einer Liste hinzugefügt a.append('x')wird oder a.extend('x)Sie sort()am Ende auch nicht verketten können. Es muss in 2 Zeilen aufgeteilt werden. Es wäre schöner gewesen, wenn die Methoden die Liste zurückgegeben hätten! docs.python.org/3/tutorial/datastructures.html Dieselbe Nachricht hat mich dabei gebissen . Folglich müssen Sie das Ding in zwei Zeilen .sort() sorted()l = ['1']; l = sorted(l.append('2'))
aufteilen.
Ich möchte auch hinzufügen, dass es sich lohnt, sich das anzuschauen: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers In meinem Fall habe ich bereits darüber nachgedacht, von einer Liste zu einem Set umzugestalten , da ich dies nicht getan habe Ich wollte Duplikate und suchte dann nach einer SortedSet-Implementierung und fand keine im Sammlungsmodul ... Quelle: stackoverflow.com/questions/5953205/…
JGFMK
3
Warum wurde die sortFunktion so gestaltet? Gibt es einen Leistungsaufwand oder andere Nachteile, wenn die sortierte Liste anstelle von Keine zurückgegeben wird?
Lei Yang
1
Ich stand auch vor dem folgenden Problem: print(newList.sort())gab None. Aber als ich es tat newList.sort()und dann print(newList)funktionierte es.
Kots
134

Das Problem ist hier:

answer = newList.sort()

sortgibt die sortierte Liste nicht zurück; Vielmehr wird die Liste sortiert.

Verwenden:

answer = sorted(newList)
NPE
quelle
4
Dies ist, was die meisten brauchen: Unterschied zwischen list.sort()und sorted(list).
Geekoverdose
62

Hier ist eine E-Mail von Guido van Rossum in Pythons Entwicklerliste, in der erklärt wird, warum er sich dafür entscheidet, keine selfOperationen zurückzugeben, die sich auf das Objekt auswirken, und keine neuen zurückzugeben.

Dies kommt von einem Codierungsstil (der in verschiedenen anderen Sprachen beliebt ist, ich glaube, besonders Lisp schwelgt darin), bei dem eine Reihe von Nebenwirkungen auf ein einzelnes Objekt wie folgt verkettet werden können:

 x.compress().chop(y).sort(z)

das wäre das gleiche wie

  x.compress()
  x.chop(y)
  x.sort(z)

Ich finde die Verkettung eine Bedrohung für die Lesbarkeit; es erfordert, dass der Leser mit jeder der Methoden vertraut ist. Die zweite Form macht deutlich, dass jeder dieser Aufrufe auf dasselbe Objekt wirkt. Selbst wenn Sie die Klasse und ihre Methoden nicht sehr gut kennen, können Sie verstehen, dass der zweite und dritte Aufruf auf x angewendet werden (und das Alle Anrufe werden wegen ihrer Nebenwirkungen getätigt) und nicht wegen etwas anderem.

Ich möchte die Verkettung für Operationen reservieren, die neue Werte zurückgeben, wie z. B. Zeichenfolgenverarbeitungsoperationen:

 y = x.rstrip("\n").split(":").lower()
Gonzalo Larralde
quelle
33
Amüsanterweise split(":").lower()ist es eine schlechte Kette, weil spliteine Liste zurückgegeben wird, die keine lowerMethode hat.
SuperBiasedMan
14

Python kehrt gewöhnlich Nonevon Funktionen und Methoden zurück, die die Daten mutieren, wie z. B. list.sort, list.appendund random.shufflemit der Idee, dass es auf die Tatsache hinweist, dass es mutiert.

Wenn Sie eine Iterable verwenden und eine neue, sortierte Liste ihrer Elemente zurückgeben sortedmöchten , verwenden Sie die integrierte Funktion.

Mike Graham
quelle
14

Python hat zwei Arten von Sorten: eine Sortierverfahren (oder „Elementfunktion“) und eine Sortierfunktion . Die Sortiermethode verarbeitet den Inhalt des genannten Objekts. Stellen Sie sich das als eine Aktion vor, die das Objekt ausführt, um sich selbst neu zu ordnen . Die Sortierfunktion ist eine Operation über die von einem Objekt dargestellten Daten und gibt ein neues Objekt mit demselben Inhalt in einer sortierten Reihenfolge zurück.

Bei einer Liste von Ganzzahlen mit dem Namen wird ldie Liste selbst neu angeordnet, wenn wir Folgendes aufrufen l.sort():

>>> l = [1, 5, 2341, 467, 213, 123]
>>> l.sort()
>>> l
[1, 5, 123, 213, 467, 2341]

Diese Methode hat keinen Rückgabewert. Aber was ist, wenn wir versuchen, das Ergebnis von zuzuweisen l.sort()?

>>> l = [1, 5, 2341, 467, 213, 123]
>>> r = l.sort()
>>> print(r)
None

rjetzt ist eigentlich nichts mehr. Dies ist eines dieser seltsamen, etwas nervigen Details, die ein Programmierer nach einer Abwesenheit von Python wahrscheinlich vergessen wird (weshalb ich dies schreibe, also ich es nicht wieder vergesse).

Die Funktion sorted()hingegen ändert nichts am Inhalt von l, gibt jedoch eine neue, sortierte Liste mit demselben Inhalt zurück wie l:

>>> l = [1, 5, 2341, 467, 213, 123]
>>> r = sorted(l)
>>> l
[1, 5, 2341, 467, 213, 123]
>>> r
[1, 5, 123, 213, 467, 2341]

Beachten Sie, dass es sich bei dem zurückgegebenen Wert nicht um eine tiefe Kopie handelt. Seien Sie daher bei Nebenwirkungen wie bei Elementen, die in der Liste enthalten sind, wie gewohnt vorsichtig:

>>> spam = [8, 2, 4, 7]
>>> eggs = [3, 1, 4, 5]
>>> l = [spam, eggs]
>>> r = sorted(l)
>>> l
[[8, 2, 4, 7], [3, 1, 4, 5]]
>>> r
[[3, 1, 4, 5], [8, 2, 4, 7]]
>>> spam.sort()
>>> eggs.sort()
>>> l
[[2, 4, 7, 8], [1, 3, 4, 5]]
>>> r
[[1, 3, 4, 5], [2, 4, 7, 8]]
zxq9
quelle
3

Um zu verstehen, warum die Liste nicht zurückgegeben wird:

sort () gibt keinen Wert zurück, während die sort () -Methode nur die Elemente einer bestimmten Liste in einer bestimmten Reihenfolge sortiert - aufsteigend oder absteigend ohne einen Wert zurückzugeben.

Das Problem ist also, answer = newList.sort()wo die Antwort keine ist.

Stattdessen können Sie einfach tun return newList.sort().

Die Syntax der sort () -Methode lautet:

list.sort(key=..., reverse=...)

Alternativ können Sie für denselben Zweck auch die in Python integrierte Funktion sorted () verwenden.

sorted(list, key=..., reverse=...)

Hinweis: Der einfachste Unterschied zwischen sort () und sorted () besteht darin, dass sort () keinen Wert zurückgibt, während sorted () eine iterierbare Liste zurückgibt.

Also in deinem Fall answer = sorted(newList).

Projesh Bhoumik
quelle
0

Sie können die sorted () -Methode verwenden, wenn die sortierte Liste zurückgegeben werden soll. Es ist bequemer.

l1 = []
n = int(input())

for i in range(n):
  user = int(input())
  l1.append(user)
sorted(l1,reverse=True)

Die Methode list.sort () ändert die Liste direkt und gibt None zurück.

Wenn Sie weiterhin sort verwenden möchten, können Sie dies tun.

l1 = []
n = int(input())

for i in range(n):
  user = int(input())
  l1.append(user)
l1.sort(reverse=True)
print(l1)
user8153007
quelle