Pourquoi «return list.sort ()» renvoie None, pas la liste?

155

J'ai pu vérifier que le findUniqueWordsrésultat est un tri list. Cependant, il ne renvoie pas la liste. Pourquoi?

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
la source
Je ne pense pas que vous ayez besoin de transformer un élément en une chaîne autant de fois. Une fois suffit normalement et il est plus propre de le faire également sur l'entrée pour nettoyer.
Ben le
3
Juste une pensée idiote, mais si vous voulez une liste d'objets uniques, pourquoi ne pas simplement les convertir en un ensemble? Vous pouvez ensuite les reconvertir en liste si vous en avez besoin. theSet= set(theList) Et vous avez terminé, il vous suffit de le renvoyer à la liste: theList = list(theSet) Terminé. Facile.
runlevel0
1
Ajout à ce que @ runlevel0 a dit (ce qui est une bonne idée): Vous pouvez convertir un theSet' into a sorted list with fichier trié (theSet) `.
Zaz
langue très irrégulière
nicolas
C'est un choix philosophique fondamental - mais problématique / irritant - de la langue. Le chaînage en général est un concept orphelin en python.
javadba le

Réponses:

195

list.sorttrie la liste en place, c'est-à-dire qu'elle ne renvoie pas de nouvelle liste. Ecrivez

newList.sort()
return newList
Ismail Badawi
la source
18
return sorted(newList)est plus court. Peu importe ici puisque la variable est locale, mais le tri sur place peut changer une variable partagée dans certains cas.
Jean-François Fabre
Il est intéressant de noter que si une entrée est ajoutée à une liste, que ce soit a.append('x'), ou a.extend('x)vous ne pouvez pas la chaîne sort()à la fin non plus . Il doit être divisé en 2 lignes. Cela aurait été mieux si les méthodes avaient renvoyé la liste! docs.python.org/3/tutorial/datastructures.html Ce même message m'a mordu en faisant exactement cela. Par conséquent, vous devez diviser la chose en deux lignes, vous devez utiliser .sort() NOT sorted() sur la liste après, car cela génère la même erreur l = ['1']; l = sorted(l.append('2'))(je viens d'ajouter un point-virgule pour que vous puissiez couper / coller et exécuter)
JGFMK
J'ajouterais également que cela vaut peut-être la peine de regarder ceci: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers Dans mon, je pensais déjà à refactoriser d'une liste à un ensemble, puisque je ne l'ai pas veulent des doublons, et recherchait alors une implémentation de SortedSet, et
je
3
Pourquoi lasort fonction a- t-elle été conçue de cette façon? y a-t-il une surcharge de performances ou d'autres inconvénients si le renvoi de la liste triée au lieu de Aucun?
Lei Yang
1
J'ai également fait face au problème suivant: print(newList.sort())donné None. Cependant, quand je l'ai fait, newList.sort()puis print(newList)cela a fonctionné.
Kots
136

Le problème est ici:

answer = newList.sort()

sortne renvoie pas la liste triée; il trie plutôt la liste en place.

Utilisation:

answer = sorted(newList)
NPE
la source
5
C'est ce dont la plupart auront besoin: la différence entre list.sort()et sorted(list).
geekoverdose
62

Voici un e-mail de Guido van Rossum dans la liste des développeurs de Python expliquant pourquoi il a choisi de ne pas revenir selfsur les opérations qui affectent l'objet et de ne pas en renvoyer une nouvelle.

Cela vient d'un style de codage (populaire dans divers autres langages, je crois que Lisp s'en délecte surtout) où une série d'effets secondaires sur un seul objet peut être enchaînée comme ceci:

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

ce qui serait le même que

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

Je trouve que le chaînage menace la lisibilité; elle exige que le lecteur soit intimement familiarisé avec chacune des méthodes. La deuxième forme indique clairement que chacun de ces appels agit sur le même objet, et donc même si vous ne connaissez pas très bien la classe et ses méthodes, vous pouvez comprendre que le deuxième et le troisième appel sont appliqués à x (et que tous les appels sont faits pour leurs effets secondaires), et non vers autre chose.

Je souhaite réserver le chaînage pour les opérations qui renvoient de nouvelles valeurs, comme les opérations de traitement de chaînes:

 y = x.rstrip("\n").split(":").lower()
Gonzalo Larralde
la source
33
De manière amusante, split(":").lower()c'est une mauvaise chaîne car splitrenvoie une liste qui n'a pas de lowerméthode.
SuperBeasedMan
14

Python habituellement les retours Nonede fonctions et des méthodes qui mutent les données, telles que list.sort, list.appendet random.shuffle, avec l'idée étant que le fait allusion qu'il a été de muter.

Si vous souhaitez prendre un itérable et renvoyer une nouvelle liste triée de ses éléments, utilisez la sortedfonction intégrée.

Mike Graham
la source
14

Python a deux sortes de sortes: une méthode de tri (ou "fonction membre") et une fonction de tri . La méthode sort opère sur le contenu de l'objet nommé - considérez-le comme une action que l'objet prend pour se réorganiser . La fonction de tri est une opération sur les données représentées par un objet et renvoie un nouvel objet avec le même contenu dans un ordre trié.

Étant donné une liste d'entiers nommés, lla liste elle-même sera réorganisée si nous appelons l.sort():

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

Cette méthode n'a pas de valeur de retour. Mais que faire si nous essayons d'attribuer le résultat de l.sort()?

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

rmaintenant équivaut à rien. C'est l'un de ces détails étranges et quelque peu ennuyeux qu'un programmeur est susceptible d'oublier après une période d'absence de Python (c'est pourquoi j'écris ceci, donc je n'oublie pas à nouveau).

La fonction sorted(), par contre, ne fera rien sur le contenu de l, mais renverra une nouvelle liste triée avec le même contenu 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]

Sachez que la valeur renvoyée n'est pas une copie complète, soyez donc prudent avec les opérations à effet secondaire sur les éléments contenus dans la liste comme d'habitude:

>>> 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
la source
4

Pour comprendre pourquoi il ne renvoie pas la liste:

sort () ne renvoie aucune valeur tandis que la méthode sort () trie simplement les éléments d'une liste donnée dans un ordre spécifique - croissant ou décroissant sans renvoyer aucune valeur.

Le problème est donc de savoir answer = newList.sort()où la réponse est aucune.

Au lieu de cela, vous pouvez simplement le faire return newList.sort().

La syntaxe de la méthode sort () est:

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

Alternativement, vous pouvez également utiliser la fonction intégrée de Python sorted () dans le même but.

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

Remarque: la différence la plus simple entre sort () et sorted () est: sort () ne renvoie aucune valeur tandis que sorted () renvoie une liste itérative.

Donc dans votre cas answer = sorted(newList).

Projesh Bhoumik
la source
0

vous pouvez utiliser la méthode sorted () si vous souhaitez qu'elle renvoie la liste triée. C'est plus pratique.

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

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

La méthode list.sort () modifie la liste sur place et renvoie None.

si vous souhaitez toujours utiliser le tri, vous pouvez le faire.

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

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