2011-09-04 2 views
64

Sono stato in grado di verificare che lo findUniqueWords ha come risultato un list ordinato. Tuttavia, non è return il list, perché?Perché "return list.sort()" restituisce None, non la lista?

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 
+0

non mi th inchiostro è necessario trasformare l'oggetto in una stringa tante volte. Una volta è abbastanza normale ed è più pulito farlo anche nell'input di cleanUp. – Ben

+0

Solo un pensiero sciocco, ma se vuoi una lista di oggetti unici, perché non ti converti in un set? È quindi possibile riconvertirli in un elenco se necessario. 'il set da = set (theList)' e si è fatto, avete solo bisogno di lanciare di nuovo alla lista: 'theList = lista (il set da)' Fatto. Facile. – runlevel0

risposta

78

list.sort ordina l'elenco in posizione, ovvero non restituisce un nuovo elenco. Basta scrivere

newList.sort() 
return newList 
+0

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

-6

Si prega di ri-leggere la documentazione per la funzione Python sort, concentrandosi sul suo valore di ritorno.

+11

-1. Per favore rileggi la domanda Ha chiesto "Perché?". Gli sviluppatori Python probabilmente hanno una ragione. La documentazione non include la motivazione per le scelte progettuali della funzione, ma solo il comportamento della funzione. – Tarrasch

75

Il problema è qui:

answer = newList.sort() 

sort non restituisce la lista ordinata; piuttosto, ordina la lista in atto.

Usa:

answer = sorted(newList) 
10

Python ritorna abitualmente None dalle funzioni e metodi che mutano i dati, come ad esempio list.sort, list.append, e random.shuffle, con l'idea è che si allude al fatto che è stato mutando.

Se si desidera eseguire un iterable e restituire un nuovo elenco ordinato dei suoi elementi, utilizzare la funzione incorporata sorted.

44

Here è un'e-mail da Guido van Rossum nella lista dev di python che spiega perché ha scelto di non restituire self sulle operazioni che riguardano l'oggetto e non ne restituiscono uno nuovo.

Questo deriva da uno stile di codifica (popolare in diverse altre lingue, ho credo festini soprattutto Lisp in esso), dove una serie di effetti collaterali su un singolo oggetto può essere incatenato come questo:

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

che sarebbe lo stesso di

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

trovo il concatenamento formare una minaccia per la leggibilità; richiede che il lettore debba conoscere intimamente ciascuno dei metodi. Il secondo modulo di chiarisce che ognuna di queste chiamate agisce sullo stesso oggetto e quindi anche se non si conosce bene la classe e i suoi metodi , è possibile capire che la seconda e la terza chiamata vengono applicate a x (e che tutte le chiamate sono fatte per i loro effetti collaterali), e non a qualcos'altro.

vorrei riservare concatenamento per le operazioni che restituiscono nuovi valori, come operazioni di elaborazione stringa:

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

In modo divertente, 'split (": "). Lower()' è una catena danneggiata perché 'split' restituisce una lista che non ha un metodo' lower'. – SuperBiasedMan

7

Python ha due tipi di specie: una sorta metodo (o "funzione membro ") e una funzione .Il metodo sort opera sui contenuti dell'oggetto denominato - pensatelo 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 gli stessi contenuti in un ordine ordinato.

Dato un elenco di numeri interi di nome l lista stessa 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 alcun valore di ritorno. Ma cosa succede se proviamo ad assegnare il risultato di l.sort()?

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

r ora equivale effettivamente a nulla. Questo è uno di quei dettagli strani, un po 'fastidiosi che un programmatore probabilmente dimenticherà dopo un periodo di assenza da Python (motivo per cui sto scrivendo questo, quindi I non dimenticarlo più).

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

Essere consapevoli del fatto che la restituito il valore è non un deep copy, in modo da essere cauti circa le operazioni di side-effecty oltre elementi contenuti all'interno della lista, 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]]