¿Por qué "return list.sort ()" devuelve None, not the list?

154

He podido verificar que el findUniqueWordsresultado es ordenado list. Sin embargo, no devuelve la lista. ¿Por qué?

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
fuente
No creo que necesites convertir el elemento en una cadena tantas veces. Una vez es normalmente suficiente y también es más limpio hacerlo en la entrada para limpiar.
Ben
3
Solo un pensamiento tonto, pero si quieres una lista de artículos únicos, ¿por qué no te conviertes en un conjunto? Luego puede convertirlos nuevamente a una lista si lo necesita. theSet= set(theList) Y ya está, solo necesita devolverlo a la lista: theList = list(theSet) Listo. Fácil.
runlevel0
1
Agregando a lo que dijo @ runlevel0 (que es una buena idea): puede convertir un theSet' into a sorted list with ordenado (theSet) `.
Zaz
lenguaje muy irregular
nicolas
Esta es una elección filosófica central, pero problemática / irritante , del idioma. El encadenamiento en general es un concepto huérfano en python.
Java

Respuestas:

194

list.sortordena la lista en su lugar, es decir, no devuelve una nueva lista. Solo escribe

newList.sort()
return newList
Ismail Badawi
fuente
18
return sorted(newList)Es más corto. No importa aquí ya que la variable es local, pero la ordenación in situ podría cambiar una variable compartida en algunos casos.
Jean-François Fabre
Es interesante que si una entrada se agrega a una lista, ya sea a.append('x')o a.extend('x)no puede encadenar sort()en el extremo tampoco. Tiene que dividirse en 2 líneas. ¡Hubiera sido mejor si los métodos devolvieran la lista! docs.python.org/3/tutorial/datastructures.html Este mismo mensaje me mordió al hacer eso. En consecuencia, debe dividir la cosa en dos líneas, luego debe usar .sort() NO sorted() en la lista, ya que esto genera el mismo error l = ['1']; l = sorted(l.append('2'))(acabo de agregar punto y coma para que pueda cortar / pegar y ejecutar)
JGFMK
También agregaría que vale la pena ver esto: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers En mi, ya estaba pensando en refactorizar de una lista a un conjunto, ya que no lo hice quería duplicados, y luego estaba buscando una implementación de SortedSet, y no encontré una en el módulo de colecciones ... Fuente: stackoverflow.com/questions/5953205/…
JGFMK
3
¿Por qué se sortdiseñó la función de esta manera? ¿hay alguna sobrecarga de rendimiento u otros inconvenientes si devuelve la lista ordenada en lugar de None?
Lei Yang el
1
También me enfrenté al siguiente problema: print(newList.sort())di None. Sin embargo, cuando lo hice, newList.sort()y luego print(newList)funcionó.
Kots
135

El problema está aquí:

answer = newList.sort()

sortno devuelve la lista ordenada; más bien, ordena la lista en su lugar.

Utilizar:

answer = sorted(newList)
NPE
fuente
55
Esto es lo que la mayoría necesitará: diferencia entre list.sort()y sorted(list).
geekoverdose
62

Aquí hay un correo electrónico de Guido van Rossum en la lista de desarrolladores de Python que explica por qué elige no regresar selfa las operaciones que afectan el objeto y no devolver uno nuevo.

Esto proviene de un estilo de codificación (popular en varios otros idiomas, creo que especialmente Lisp se deleita con él) donde una serie de efectos secundarios en un solo objeto se pueden encadenar así:

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

que sería lo mismo que

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

Encuentro que el encadenamiento es una amenaza para la legibilidad; requiere que el lector debe estar íntimamente familiarizado con cada uno de los métodos. La segunda forma deja en claro que cada una de estas llamadas actúa sobre el mismo objeto, por lo que incluso si no conoce muy bien la clase y sus métodos, puede comprender que la segunda y la tercera llamada se aplican a x (y que todas las llamadas se hacen por sus efectos secundarios), y no a otra cosa.

Me gustaría reservar el encadenamiento para operaciones que devuelven nuevos valores, como las operaciones de procesamiento de cadenas:

 y = x.rstrip("\n").split(":").lower()
Gonzalo Larralde
fuente
33
Divertidamente, split(":").lower()es una mala cadena porque splitdevuelve una lista que no tiene un lowermétodo.
SuperBiasedMan
14

Python habitualmente regresa Nonede funciones y métodos que mutan los datos, como list.sort, list.appendy random.shuffle, con la idea de que sugiere el hecho de que estaba mutando.

Si desea tomar un iterable y devolver una nueva lista ordenada de sus elementos, use la sortedfunción incorporada.

Mike Graham
fuente
14

Python tiene dos tipos de clasificaciones: un método de clasificación (o "función miembro") y una función de clasificación . El método de clasificación opera en el contenido del objeto nombrado; piense en él como una acción que el objeto está tomando para reordenarse a sí mismo . La función de clasificación es una operación sobre los datos representados por un objeto y devuelve un nuevo objeto con el mismo contenido en un orden ordenado.

Dada una lista de enteros llamada lla lista misma se reordenará si llamamos a l.sort():

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

Este método no tiene valor de retorno. Pero, ¿y si tratamos de asignar el resultado de l.sort()?

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

rahora es igual a nada en realidad. Este es uno de esos extraños detalles, algo molesto que un programador es probable que se olvide de después de un período de ausencia del Python (que es por eso que estoy escribiendo esto, así que no me olvido otra vez).

La función sorted(), por otro lado, no hará nada al contenido de l, pero devolverá una nueva lista ordenada con el mismo contenido que 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]

Tenga en cuenta que el valor devuelto no es una copia profunda , así que tenga cuidado con las operaciones de efectos secundarios sobre los elementos contenidos en la lista como de costumbre:

>>> 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
fuente
4

Para entender por qué no devuelve la lista:

sort () no devuelve ningún valor, mientras que el método sort () simplemente clasifica los elementos de una lista dada en un orden específico: ascendente o descendente sin devolver ningún valor.

Entonces el problema es con answer = newList.sort()donde la respuesta es ninguna.

En cambio, solo puedes hacer return newList.sort().

La sintaxis del método sort () es:

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

Alternativamente, también puede usar la función incorporada de Python sorted () para el mismo propósito.

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

Nota: La diferencia más simple entre sort () y sorted () es: sort () no devuelve ningún valor, mientras sorted () devuelve una lista iterable.

Entonces en tu caso answer = sorted(newList).

Projesh Bhoumik
fuente
0

puede usar el método sorted () si desea que devuelva la lista ordenada. Es mas conveniente.

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

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

El método list.sort () modifica la lista en el lugar y devuelve None.

si aún quieres usar sort, puedes hacerlo.

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

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