Por que "return list.sort ()" retorna None, não a lista?

154

Consegui verificar se isso findUniqueWordsresulta em uma classificação list. No entanto, ele não retorna a 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
fonte
Eu não acho que você precise transformar o item em uma string tantas vezes. Uma vez é normalmente suficiente e é mais limpo fazê-lo na entrada para limpar também.
Ben
3
Apenas um pensamento tolo, mas se você deseja uma lista de itens exclusivos, por que não se converte em um conjunto? Você pode convertê-los novamente em uma lista, se necessário. theSet= set(theList) E pronto, você só precisa devolvê-lo à lista: theList = list(theSet) Concluído. Fácil.
usar o seguinte
1
Adicionando ao que @ runlevel0 disse (o que é uma boa idéia): Você pode converter um theSet' into a sorted list with ordenado (theSet) `.
Zaz
linguagem muito irregular
nicolas
Essa é uma escolha filosófica básica - mas problemática / irritante - da linguagem. Encadeamento em geral é um conceito órfão em python.
javadba 3/01

Respostas:

194

list.sortclassifica a lista no local, ou seja, ela não retorna uma nova lista. Apenas escreva

newList.sort()
return newList
Ismail Badawi
fonte
18
return sorted(newList)é mais curto. Não importa aqui, pois a variável é local, mas a classificação no local pode alterar uma variável compartilhada em alguns casos.
Jean-François Fabre
É interessante que, se uma entrada é adicionado a uma lista, a.append('x')ou a.extend('x)você não pode cadeia sort()no final também. Ele deve ser dividido em 2 linhas. Teria sido melhor se os métodos retornassem a lista! docs.python.org/3/tutorial/datastructures.html Essa mesma mensagem me mordeu fazendo exatamente isso. Conseqüentemente, você tem que quebrar a coisa em duas linhas, você tem que usar .sort() NOT sorted() na lista a seguir, uma vez que este gera o mesmo erro l = ['1']; l = sorted(l.append('2'))(I acabou de adicionar ponto e vírgula para que você poderia cortar / colar e funcionamento)
JGFMK
Eu também acrescentaria que pode valer a pena olhar para isso: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers No meu, eu já estava pensando em refatorar de uma lista para um conjunto, pois não quer duplicatas e foi então à procura de uma implementação de SortedSet, e não encontrar um em coleções de módulos ... Fonte: stackoverflow.com/questions/5953205/...
JGFMK
3
Por que asort função foi projetada dessa maneira? há alguma sobrecarga de desempenho ou outras desvantagens se retornar a lista classificada em vez de Nenhuma?
Lei Yang
1
Eu também enfrentei o seguinte problema: print(newList.sort())deu None. No entanto, quando eu fiz, newList.sort()e então print(newList)funcionou.
Kots
135

O problema está aqui:

answer = newList.sort()

sortnão retorna a lista classificada; em vez disso, classifica a lista no lugar.

Usar:

answer = sorted(newList)
NPE
fonte
5
É disso que a maioria precisará: diferença entre list.sort()e sorted(list).
Geekoverdose
62

Aqui está um e-mail de Guido van Rossum na lista de desenvolvedores do Python, explicando por que ele escolhe não retornar as selfoperações que afetam o objeto e não retorna um novo.

Isso vem de um estilo de codificação (popular em várias outras línguas, acredito que especialmente o Lisp se deleita), onde uma série de efeitos colaterais em um único objeto pode ser encadeada da seguinte maneira:

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

o que seria o mesmo que

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

Acho a forma de encadeamento uma ameaça à legibilidade; requer que o leitor esteja intimamente familiarizado com cada um dos métodos. A segunda forma deixa claro que cada uma dessas chamadas atua no mesmo objeto e, mesmo que você não conheça muito bem a classe e seus métodos, você pode entender que a segunda e a terceira chamada são aplicadas a x (e que todas as chamadas são feitas por seus efeitos colaterais) e não para outra coisa.

Gostaria de reservar o encadeamento para operações que retornam novos valores, como operações de processamento de string:

 y = x.rstrip("\n").split(":").lower()
Gonzalo Larralde
fonte
33
Divertidamente, split(":").lower()é uma cadeia ruim porque splitretorna uma lista que não possui um lowermétodo.
SuperBiasedMan
14

Python habitualmente retornos Nonede funções e métodos que transformam os dados, tais como list.sort, list.appende random.shuffle, com a idéia de que ele sugere para o facto de ter sido mutação.

Se você deseja fazer uma iterável e retornar uma nova lista classificada de seus itens, use a sortedfunção interna.

Mike Graham
fonte
14

O Python possui dois tipos de classificação: um método de classificação (ou "função de membro") e uma função de classificação . O método de classificação opera no conteúdo do objeto nomeado - pense nele como uma ação que o objeto está executando para se reordenar . A função de classificação é uma operação sobre os dados representados por um objeto e retorna um novo objeto com o mesmo conteúdo em uma ordem classificada.

Dada uma lista de números inteiros nomeados, la própria lista será reordenada se chamarmos l.sort():

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

Este método não tem valor de retorno. Mas e se tentarmos atribuir o resultado l.sort()?

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

ragora é igual a nada. Esta é uma daquelas estranhas detalhes, um pouco irritante que um programador é provável que esquecer depois de um período de ausência do Python (que é por isso que eu estou escrevendo isso, então eu não se esqueça de novo).

A função sorted(), por outro lado, não fará nada com o conteúdo de l, mas retornará uma nova lista classificada com o mesmo conteúdo 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]

Esteja ciente de que o valor retornado não é uma cópia detalhada; portanto, tenha cuidado com operações com efeitos colaterais sobre os elementos contidos na lista, como de costume:

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

Para entender por que ele não retorna a lista:

sort () não retorna nenhum valor, enquanto o método sort () apenas classifica os elementos de uma determinada lista em uma ordem específica - crescente ou decrescente sem retornar nenhum valor.

Então o problema é answer = newList.sort()onde a resposta é nenhuma.

Em vez disso, você pode simplesmente fazer return newList.sort().

A sintaxe do método sort () é:

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

Como alternativa, você também pode usar a função incorporada do Python classificada () para a mesma finalidade.

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

Nota: A diferença mais simples entre sort () e ordenada () é: sort () não retorna nenhum valor enquanto, classificada () retorna uma lista iterável.

Então no seu caso answer = sorted(newList).

Projesh Bhoumik
fonte
0

você pode usar o método classificado () se desejar retornar a lista classificada. É mais conveniente.

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

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

O método list.sort () modifica a lista no local e retorna Nenhum.

Se você ainda deseja usar a classificação, pode fazer isso.

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

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