Perché "return list.sort ()" restituisce None, non l'elenco?


155

Sono stato in grado di verificare che findUniqueWordsciò comporti un ordinamento list. Tuttavia, non restituisce l'elenco. Perché?

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

Non penso che devi trasformare l'oggetto in una stringa così tante volte. Una volta è abbastanza ed è più pulito farlo anche sull'input di cleanUp.
Ben

3
Solo un pensiero sciocco, ma se vuoi un elenco di oggetti unici, perché non ti converti in un set? È quindi possibile riconvertirli in un elenco, se necessario. theSet= set(theList) E il gioco è fatto, devi solo ricondurlo all'elenco: theList = list(theSet) Fatto. Facile.
runlevel0,

1
Aggiungendo a ciò che ha detto @ runlevel0 (che è una buona idea): puoi convertire un theSet' into a sorted list with ordinato (theSet) `.
Zaz,

linguaggio molto irregolare
nicolas

Questa è una scelta filosofica fondamentale, ma problematica / irritante . Il concatenamento in generale è un concetto orfano in pitone.
Javavba,

Risposte:


195

list.sortordina l'elenco in atto, ovvero non restituisce un nuovo elenco. Scrivi e basta

newList.sort()
return newList

18
return sorted(newList)è più corto. Non importa qui poiché la variabile è locale, ma l'ordinamento sul posto potrebbe modificare una variabile condivisa in alcuni casi.
Jean-François Fabre

È interessante notare che se una voce viene aggiunta a un elenco a.append('x')o a.extend('x)se non è possibile eseguire la catena sort()alla fine. Deve essere diviso in 2 righe. Sarebbe stato più bello se i metodi avessero restituito l'elenco! docs.python.org/3/tutorial/datastructures.html Questo stesso messaggio mi ha morso facendo proprio questo. Di conseguenza devi dividere la cosa in due righe, in seguito devi usare .sort() NOT sorted() nell'elenco, poiché questo genera lo stesso errore l = ['1']; l = sorted(l.append('2'))(ho appena aggiunto i punti e virgola in modo da poter tagliare / incollare ed eseguire)
JGFMK

Vorrei anche aggiungere che vale la pena dare un'occhiata a questo: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers Nel mio, stavo già pensando di refactoring da un elenco a un set, dal momento che non l'ho fatto vogliono duplicati, e fu poi alla ricerca di un'implementazione SortedSet, e non ha trovato uno in collezioni modulo ... Fonte: stackoverflow.com/questions/5953205/...
JGFMK

3
Perché lasort funzione è stata progettata in questo modo? c'è qualche sovraccarico prestazionale o altri svantaggi se restituisce l'elenco ordinato anziché Nessuno?
Lei Yang,

1
Ho anche affrontato il problema folowing: ha print(newList.sort())dato None. Tuttavia, quando l'ho fatto, newList.sort()e poi print(newList)ha funzionato.
Kots

136

Il problema è qui:

answer = newList.sort()

sortnon restituisce l'elenco ordinato; piuttosto, ordina l'elenco in atto.

Uso:

answer = sorted(newList)

5
Questo è ciò di cui la maggior parte avrà bisogno: differenza tra list.sort()e sorted(list).
geekoverdose,

62

Ecco un'e-mail di Guido van Rossum nell'elenco degli sviluppatori di Python che spiega perché ha scelto di non tornare selfsulle operazioni che interessano l'oggetto e di non restituirne uno nuovo.

Questo deriva da uno stile di codifica (popolare in varie altre lingue, credo soprattutto in Lisp) in cui una serie di effetti collaterali su un singolo oggetto può essere concatenata in questo modo:

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

che sarebbe lo stesso di

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

Trovo la forma concatenata una minaccia alla leggibilità; richiede che il lettore debba avere un'intima familiarità con ciascuno dei metodi. Il secondo modulo chiarisce che ognuna di queste chiamate agisce sullo stesso oggetto e quindi anche se non conosci molto bene la classe e i suoi metodi, puoi capire che la seconda e la terza chiamata sono applicate a x (e che tutte le chiamate sono fatte per i loro effetti collaterali) e non per qualcos'altro.

Vorrei riservare il concatenamento per le operazioni che restituiscono nuovi valori, come le operazioni di elaborazione delle stringhe:

 y = x.rstrip("\n").split(":").lower()

33
In modo divertente, split(":").lower()è una brutta catena perché splitrestituisce un elenco che non ha un lowermetodo.
SuperBiasedMan

14

Pitone abitualmente ritorni Nonedalle funzioni e metodi che mutano i dati, ad esempio list.sort, list.appende random.shuffle, con l'idea è che allude al fatto che è stato mutando.

Se vuoi prendere un iterabile e restituire un nuovo elenco ordinato dei suoi elementi, usa la sortedfunzione integrata.


14

Python ha due tipi di ordinamenti: un metodo di ordinamento (o "funzione membro") e una funzione di ordinamento . Il metodo di ordinamento opera sul contenuto dell'oggetto denominato: pensalo come un'azione che l'oggetto sta eseguendo per riordinare se stesso . La funzione di ordinamento è un'operazione sui dati rappresentati da un oggetto e restituisce un nuovo oggetto con lo stesso contenuto in un ordine ordinato.

Dato un elenco di numeri interi chiamati ll'elenco stesso verrà riordinato se chiamiamo l.sort():

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

Questo metodo non ha valore di ritorno. E se provassimo ad assegnare il risultato di l.sort()?

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

rora non equivale a nulla. Questo è uno di quei strani, un po 'fastidiosi dettagli che un programmatore è probabile a dimenticare dopo un periodo di assenza dal Python (che è il motivo per cui sto scrivendo questo, quindi io non dimentico di nuovo).

La funzione sorted(), d'altra parte, non farà nulla al contenuto di l, ma restituirà un nuovo elenco ordinato con gli stessi contenuti di 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]

Tieni presente che il valore restituito non è una copia approfondita , quindi fai attenzione alle operazioni con effetti collaterali sugli elementi contenuti nell'elenco come al solito:

>>> 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]]

4

Per capire perché non restituisce l'elenco:

sort () non restituisce alcun valore mentre il metodo sort () ordina semplicemente gli elementi di un determinato elenco in un ordine specifico - crescente o decrescente senza restituire alcun valore.

Quindi il problema è answer = newList.sort()dove la risposta è nessuna.

Invece puoi semplicemente fare return newList.sort().

La sintassi del metodo sort () è:

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

In alternativa, puoi anche usare la funzione integrata di Python ordinata () per lo stesso scopo.

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

Nota: la differenza più semplice tra sort () e sort () è: sort () non restituisce alcun valore mentre, sort () restituisce un elenco iterabile.

Quindi nel tuo caso answer = sorted(newList).


0

puoi usare il metodo sort () se vuoi che ritorni la lista ordinata. È più conveniente.

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

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

Il metodo list.sort () modifica l'elenco sul posto e restituisce None.

se vuoi ancora usare l'ordinamento puoi farlo.

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

for i in range(n):
  user = int(input())
  l1.append(user)
l1.sort(reverse=True)
print(l1)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.