Dlaczego „return list.sort ()” zwraca Brak, nie listę?

154

Udało mi się zweryfikować, że findUniqueWordspowoduje to posortowanie list. Jednak nie zwraca listy. Czemu?

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
źródło
Myślę, że nie trzeba tyle razy zamieniać przedmiotu w ciąg. Jeden raz jest zwykle wystarczający i czystszy jest również zrobienie tego na wejściu do cleanUp.
Ben
3
Po prostu głupia myśl, ale jeśli chcesz mieć listę unikalnych przedmiotów, dlaczego po prostu nie przekształcisz się w zestaw? W razie potrzeby możesz następnie przekonwertować je z powrotem na listę. Gotowe theSet= set(theList) , wystarczy, że wrzucisz to z powrotem do listy: theList = list(theSet)Gotowe. Łatwo.
runlevel0
1
Dodając do tego, co powiedział @ runlevel0 (co jest dobrym pomysłem): Możesz przekonwertować theSet' into a sorted list with posortowany (theSet) `.
Zaz
bardzo nieregularny język
nicolas
To jest rdzeń - ale problematyczny / irytujący - filozoficzny wybór języka. Tworzenie łańcuchów jest generalnie osieroconym pojęciem w Pythonie.
javadba

Odpowiedzi:

194

list.sortsortuje listę w miejscu, tzn. nie zwraca nowej listy. Tylko napisz

newList.sort()
return newList
Ismail Badawi
źródło
18
return sorted(newList)jest krótszy. Nie ma to znaczenia, ponieważ zmienna jest lokalna, ale sortowanie w miejscu może w niektórych przypadkach zmienić wspólną zmienną.
Jean-François Fabre
To ciekawe, że jeśli wpis zostanie dodany do listy, albo a.append('x'), lub a.extend('x)nie możesz łańcuch sort()na końcu każdej. Musi być podzielony na 2 linie. Byłoby ładniej, gdyby metody zwracały listę! docs.python.org/3/tutorial/datastructures.html Ta sama wiadomość ugryzła mnie, właśnie to. W konsekwencji musisz podzielić rzecz na dwie linie, potem musisz użyć .sort() NOT sorted() na liście, ponieważ generuje to ten sam błąd l = ['1']; l = sorted(l.append('2'))(właśnie dodałem średnik, abyś mógł wyciąć / wkleić i uruchomić)
JGFMK
Dodam też, że może warto przyjrzeć się temu: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers W moim, już myślałem o refaktoryzacji z listy do zestawu, ponieważ tego nie zrobiłem chcę duplikatów, a następnie szukałem implementacji SortedSet i nie znalazłem jej w module kolekcji ... Źródło: stackoverflow.com/questions/5953205/…
JGFMK
3
Dlaczegosort funkcja została zaprojektowana w ten sposób? czy występuje jakikolwiek narzut wydajności lub inne wady, jeśli zwraca posortowaną listę zamiast Brak?
Lei Yang
1
Miałem też do czynienia z następującym problemem: print(newList.sort())dał None. Jednak kiedy to zrobiłem, newList.sort()i wtedy print(newList)zadziałało.
Kots
136

Problem jest tutaj:

answer = newList.sort()

sortnie zwraca posortowanej listy; raczej sortuje listę w miejscu.

Posługiwać się:

answer = sorted(newList)
NPE
źródło
5
To, czego większość będzie potrzebować: różnica między list.sort()i sorted(list).
geekoverdose
62

Oto e-mail od Guido van Rossuma z listy deweloperów Pythona wyjaśniający, dlaczego zdecydował się nie wracać selfdo operacji, które mają wpływ na obiekt i nie zwraca nowego.

Wynika to ze stylu kodowania (popularnego w różnych innych językach, wydaje mi się, że szczególnie lubi nim Lisp), w którym można połączyć szereg efektów ubocznych na jednym obiekcie w następujący sposób:

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

który byłby taki sam jak

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

Uważam, że tworzenie łańcuchów stanowi zagrożenie dla czytelności; wymaga, aby czytelnik dokładnie zapoznał się z każdą z metod. Druga forma wyjaśnia, że ​​każde z tych wywołań działa na tym samym obiekcie, więc nawet jeśli nie znasz zbyt dobrze klasy i jej metod, możesz zrozumieć, że drugie i trzecie wywołanie są stosowane do x (i że wszystkie wezwania dotyczą ich skutków ubocznych), a nie czegoś innego.

Chciałbym zarezerwować łańcuchy dla operacji, które zwracają nowe wartości, takie jak operacje przetwarzania łańcuchów:

 y = x.rstrip("\n").split(":").lower()
Gonzalo Larralde
źródło
33
Co zabawne, split(":").lower()to zły łańcuch, ponieważ splitzwraca listę, która nie ma lowermetody.
SuperBiasedMan
14

Python zwykle powraca Nonez funkcji i metod, które modyfikują dane, takich jak list.sort, list.appendi random.shuffle, z założeniem, że wskazuje na fakt, że ulegał mutacji.

Jeśli chcesz wziąć iterowalną i zwrócić nową, posortowaną listę jej elementów, użyj sortedfunkcji wbudowanej.

Mike Graham
źródło
14

Python ma dwa rodzaje rodzaje: rodzajem metody (lub „funkcji członka”) oraz sortowania funkcji . Metoda sort działa na zawartości nazwanego obiektu - traktuj ją jako działanie, które obiekt podejmuje w celu zmiany kolejności . Funkcja sortowania to operacja na danych reprezentowanych przez obiekt i zwraca nowy obiekt o tej samej zawartości w posortowanej kolejności.

Biorąc pod uwagę listę liczb całkowitych o nazwie, lsama lista zostanie zmieniona, jeśli wywołasz l.sort():

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

Ta metoda nie ma wartości zwracanej. Ale co, jeśli spróbujemy przypisać wynik l.sort()?

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

rteraz to właściwie nic. Jest to jedna z tych dziwnych, trochę irytujących szczegółów, które programista może zapomnieć o po okresie nieobecności w Pythonie (dlatego piszę to, tak I nie zapomnij ponownie).

Z sorted()drugiej strony funkcja nie zrobi nic z zawartością l, ale zwróci nową, posortowaną listę o tej samej zawartości co 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]

Należy pamiętać, że zwracana wartość nie jest głęboką kopią , więc jak zwykle zachowaj ostrożność w przypadku działań ubocznych na elementach zawartych na liście:

>>> 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
źródło
4

Aby zrozumieć, dlaczego nie zwraca listy:

sort () nie zwraca żadnej wartości, a metoda sort () po prostu sortuje elementy podanej listy w określonej kolejności - rosnąco lub malejąco bez zwracania żadnej wartości.

Więc problem jest z answer = newList.sort() że nie ma odpowiedzi.

Zamiast tego możesz po prostu to zrobić return newList.sort() .

Składnia metody sort () jest następująca:

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

Alternatywnie, w tym samym celu możesz również użyć wbudowanej w Pythonie funkcji sortowanej ().

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

Uwaga: Najprostsza różnica między sort () i sort () jest taka: sort () nie zwraca żadnej wartości, podczas gdy sort () zwraca iterowalną listę.

Więc w twoim przypadku answer = sorted(newList).

Projesh Bhoumik
źródło
0

możesz użyć metody sort (), jeśli chcesz, aby zwracała posortowaną listę. To jest wygodniejsze.

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

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

list.sort () modyfikuje listę w miejscu i zwraca wartość None.

jeśli nadal chcesz używać sortowania, możesz to zrobić.

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

for i in range(n):
  user = int(input())
  l1.append(user)
l1.sort(reverse=True)
print(l1)
user8153007
źródło