6
votes

Python TypeError: sort () ne prend aucun argument de position

J'essaie d'écrire une petite classe et je veux trier les éléments en fonction du poids. Le code est fourni,

class Bird:

    def __init__(self, weight):
        # __weight for the private variable
        self.__weight = weight

    def weight(self):
        return self.__weight

    def __repr__(self):
        return "Bird, weight = " + str(self.__weight)


if __name__ == '__main__':

    # Create a list of Bird objects.
    birds = []
    birds.append(Bird(10))
    birds.append(Bird(5))
    birds.append(Bird(200))

    # Sort the birds by their weights.
    birds.sort(lambda b: b.weight())

    # Display sorted birds.
    for b in birds:
        print(b)

Quand je lance le programme, j'obtiens la pile d'erreurs de Python TypeError: sort () ne prend aucun argument de position . Quel est le problème ici?


1 commentaires

Cette erreur est spécifique à python3 en fait. Python2 supposerait que la fonction donnée pour trier est une fonction cmp. Le code ci-dessus sera toujours cassé lorsque vous lui attribuez une fonction clé. J'ai trouvé ce Q parce que mon script python2 s'est cassé lors de l'exécution sous python3.


3 Réponses :


12
votes

Exactement ce qu'il dit: sort ne prend aucun argument de position. Il prend un argument de mot clé uniquement nommé key :

birds.sort(key=lambda b: b.weight())

De documentation :

sort (*, key = None, reverse = False)

Cette méthode trie la liste en place, en utilisant uniquement des comparaisons entre les éléments. Les exceptions ne sont pas supprimées - si une opération de comparaison échoue, l'opération de tri entière échouera (et la liste sera probablement laissée dans un état partiellement modifié).

sort () accepte deux arguments qui ne peuvent être transmis que par mot-clé (arguments de mots clés uniquement):

key spécifie une fonction d'un argument qui est utilisée pour extraire une clé de comparaison de chaque élément de la liste (par exemple, key = str.lower ). La clé correspondant à chaque élément de la liste est calculée une fois puis utilisée pour l'ensemble du processus de tri. La valeur par défaut de Aucun signifie que les éléments de la liste sont triés directement sans calculer une valeur de clé distincte.

[...]

Le * dans la signature est le séparateur entre les paramètres de position et les paramètres de mot-clé uniquement; sa position comme "argument" initial indique le manque de paramètres de position.


1 commentaires

Il y a une raison historique pour laquelle c'est comme ça. Au début de Python, une fonction cmp était attendue. La possibilité de passer une fonction clé plutôt qu'une fonction cmp a été ajoutée à un moment donné. La possibilité de passer la fonction cmp a été supprimée dans python3. Pour vous assurer que les anciens scripts python2 (passant une fonction cmp comme argument de position) ne rompraient pas avec une erreur encore plus obscure, sort n'accepte plus l'argument de position.



6
votes

Consulter la documentation de list.sort , nous pouvons voir que key est un argument de mot clé uniquement. Alors changez la ligne

birds.sort (lambda b: b.weight ())

à

birds.sort (key = (lambda b: b.weight ()))


2 commentaires

Cependant, vous n'avez pas besoin des parenthèses pour la clé. il suffit de key = lambda b: b.weight () .


@ alec935 Je vous prie de différer. Jetez un œil à la réponse de Chepner. Tellement plus facile à lire sans les parenthèses superflues et ça fait la même chose. Si OP a plus de code imbriqué avant le sort , combien de parenthèses fermantes est trop?



3
votes

sort () prend un argument key et rien d'autre (enfin, il peut prendre un argument reverse ). Vous avez fourni sort () avec un argument qu'il ne peut pas accepter. Ajoutez simplement une key = avant votre lambda

Le message d'erreur est dû au fait que la clé prend des arguments de mot-clé, pas des arguments de position. Un argument de position est un nom qui n'est pas suivi d'un signe égal et d'une valeur par défaut.


0 commentaires