Tri par classe Python

Motivation

Python a une fonction de tri, y compris une méthode list.sort () et une fonction sorted (). J'ai recherché un tri lié à ma propre classe, Ça y est ...! Je n'ai rien trouvé de tel, alors je vais le laisser comme mémoire.

manière

Selon Officiel, Cela peut être fait en spécifiant une fonction Key. De plus, il semble que cela puisse être fait par une surcharge d'opérateur de comparaison de classes.

Exemple avec opérateur de comparaison

Je faisais un jeu de cartes après avoir étudié Comment trier la classe Trump Au début, j'ai pensé à surcharger l'opérateur de comparaison. (Sentiment de programmeur C ++)

S'il y avait une classe Trump avec une telle suie et des chiffres (Une partie du code est omise)

class Trump:
    def __init__(self, suit, number):
        self.suit = suit
        self.number = number

Définit une surcharge d'opérateur de comparaison dans la classe Trump.

    def __lt__(self, other):
        """Opérateur de comparaison<"""
        return self.get_sort_number() < other.get_sort_number()

    def __gt__(self, other):
        """Opérateur de comparaison>"""
        return self.get_sort_number() > other.get_sort_number()

get_sort_number () définit l'ordre de disposition par la taille du nombre entier. C'est une image que la plus petite vient en premier. En termes de suie, l'ordre est pique, cœur, diamant, club et joker. Sur get_sort_number (), en ajoutant le numéro de la suie (Trump.SORT_ ~) et le nombre, Je fais trier les chiffres.

    def get_sort_number(self):
        """Obtenir un entier pour le tri"""
        n = 0
        if self.suit == Trump.SPADE:
            n = Trump.SORT_SPADE
        elif self.suit == Trump.HEART:
            n = Trump.SORT_HEART
        elif self.suit == Trump.DIAMOND:
            n = Trump.SORT_DIAMOND
        elif self.suit == Trump.CLUB:
            n = Trump.SORT_CLUB
        elif self.suit == Trump.JOKER:
            n = Trump.SORT_JOKER
        #Renvoie un nombre avec tri et nombres ajoutés
        return n + self.number

Au fait, je mettrai la définition numérique du tri Le nombre pour chaque suie est 13, il n'est donc pas nécessaire que ce soit 20, mais il est bien séparé par 20. Si c'est un chat 13 Le nombre qui peut être pris par get_sort_number () est 0 + 13 et 13 Si c'est l'un des cœurs Le nombre qui peut être pris par get_sort_number () est 20 + 1 et 21 Ce sera. Le tri se fait par la taille de ce nombre.

    SORT_SPADE = 0
    SORT_HEART = 20
    SORT_DIAMOND = 40
    SORT_CLUB = 60
    SORT_JOKER = 80

Définissez une classe TrumpHand qui rassemble ces atouts. (Pas strictement nécessaire) Vous avez simplement la classe Trump dans la liste. Lors du tri, tout ce que vous avez à faire est d'appeler la méthode de tri de liste. Il trie par ordre croissant sans autorisation.

class TrumpHand:
    def __init__(self):
        self.hand = []

    def sort(self):
        """Triez votre main"""
        self.hand.sort()

Faisons cela (L'explication de l'ajout et de l'impression est omise ~~ Vous pouvez l'imaginer juste par le nom ~~)

    #Générer une classe de main(Je l'ai juste dans la liste)
    hand = trump_hand.TrumpHand()
    #Ajoutez 1 de Joker et Club et 1 de Spade à votre main
    hand.add(trump.Trump(trump.Trump.JOKER, 1))
    hand.add(trump.Trump(trump.Trump.CLUB, 1))
    hand.add(trump.Trump(trump.Trump.SPADE, 1))
    #Sortie de l'état avant le tri
    hand.print()
    #Trier
    hand.sort()
    #Sortie de l'état après le tri
    hand.print()

Il s'agit de la sortie avant le tri. J1 (Joker), C1 (Club 1), S1 (Spade 1) et l'ordre ajouté dans le code ci-dessus.

[0]J1
[1]C1
[2]S1

Il s'agit de la sortie après le tri. S1 (1 de pique), C1 (1 de club), J1 (joker) Et get_sort_number () sont dans l'ordre exact mentionné dans l'explication.

[0]S1
[1]C1
[2]J1

problème

Ce n'était pas une fin heureuse ...

Problème 1

Est-il acceptable d'utiliser les opérateurs de comparaison de Trump dans l'ordre de tri? L'opérateur de comparaison peut également être utilisé pour comparer la force de Trump.

Problème 2

Selon les règles du jeu, la force peut changer en fonction des conditions Ou je veux que les utilisateurs puissent les voir facilement, N'est-il pas difficile d'être flexible avec la fixation?

Autrement

C'est là que le tri à l'aide de la fonction Key entre finalement en jeu. ~~ Official a déjà été écrit pour que vous n'ayez pas à consulter cet article ~~ ~~ Mais je n'ai pas compris tout de suite ~~

Cité du fonctionnaire

list.sort () et sorted () ont des paramètres clés. Il s'agit d'un paramètre qui spécifie la fonction à appeler pour chaque élément de la liste avant d'effectuer une comparaison. Le paramètre clé doit prendre un seul argument et renvoyer la clé utilisée pour le tri. Cette contrainte permet un tri plus rapide, car la fonction clé est appelée exactement une fois pour chaque enregistrement d'entrée.

manière

Vous savez que vous pouvez spécifier la fonction à utiliser pour le tri dans la fonction Clé. La question est de savoir comment créer une fonction Key,

Si vous regardez de près la formule ** Un modèle d'utilisation courant consiste à trier un objet composé de plusieurs éléments en utilisant l'un des index comme clé. ** **

Il est probable que get_sort_number () soit mentionné cette fois. Renvoyez une clé composée d'une suie et d'un élément numérique, faites-la trier, c'est tout. Lors du tri par ordre croissant, si le nombre est faible, il doit être au début, et s'il est élevé, il doit être à la fin.

Réécrivez le code en disant. ** (Note) Il est recommandé de spécifier trump.Trump.get_sort_number écrit sous cette méthode **

Avant de réécrire

    def sort(self):
        """Triez votre main"""
        self.hand.sort()

Après réécriture (expression lambda)

    def sort(self):
        """Triez votre main"""
        self.hand.sort(key=lambda x: x.get_sort_number())

Spécifiez la fonction Key avec key = lors de l'appel de la méthode de tri. Cette fois, get_sort_number () de la cible de tri (classe Trump) est retourné et utilisé pour le tri. En remarque, x est la classe Trump.

De plus, la surcharge d'opérateur de comparaison décrite ci-dessus n'est pas nécessaire, effaçons-la. Je l'ai écrit dans un style lambda, mais si je l'écris normalement, ce serait comme ça. (Non vérifié)

#Définition de la fonction clé quelque part
def get_sort_key(x):
    return x.get_sort_number()

    #Réécrire le tri(Spécifier la fonction clé)
    def sort(self):
        """Triez votre main"""
        self.hand.sort(key=get_sort_key)

Méthode recommandée

2020/04/19 18:00 PostScript Ceci est recommandé car l'intention du programme est plus claire que @shiracamus (opération vérifiée) Merci pour votre commentaire

Avant de réécrire

    def sort(self):
        """Triez votre main"""
        self.hand.sort()

Après la réécriture (spécifiez trump.Trump.get_sort_number dans la fonction clé)

    def sort(self):
        """Triez votre main"""
        self.hand.sort(key=trump.Trump.get_sort_number)

C'est ce qui se produit lorsque vous exécutez la version qui spécifie la fonction Key.

Sortie avant tri

[0]J1
[1]C1
[2]S1

Sortie après tri

[0]S1
[1]C1
[2]J1

Oui, il a la même sortie que l'opérateur de comparaison. Si vous modifiez la spécification de la fonction Clé en fonction de la situation et des spécifications, vous pourrez trier de manière flexible.

~~ Repentir ~~

~~ Python a été lancé il y a quelques jours, donc je suis désolé s'il y a quelque chose qui ne va pas ~~ ~~ La classe Trump peut être placée dans une opération variable par bit, mais la priorité est donnée à la clarté ~~ ~~ get_sort_number () Vous pouvez l'écrire plus court ~~

Recommended Posts

Tri par classe Python
[Python] Trier
Python #sort
[Python] classe, instance
"Kanrika" la classe python
À propos de python, classe
classe python, instance
Les bases de #Python (classe)
classe wrapper python syslog
Classe Python (mémo d'apprentissage Python ⑦)
classe de cas en python
Tri à bulles en Python
[Python] Héritage de classe (super)
[python] méthode de base de la classe
[Python] Héritage de classe, remplacement
[Mémo] Tri de liste Python3
classe de wrapper de sous-processus python
Feuille de triche de tri Python
Tri personnalisé en Python3
[Python] Trier les types de collection
Classe wrapper YOLO Python
Notation de classe en Python
Liste des classes d'exception Python
compilateur x86 réalisé avec python
Python: variables de classe et d'instance
[Python] Chargement de modules personnalisés à plusieurs niveaux
Trier naturellement le chemin en Python
Un programmeur C / C ++ défie Python (édition de classe)
Ordre de tri des dict de base Python
Trier de gros fichiers avec python
Résumé de la portée des membres de la classe Python
Tri décroissant avec mongodb en python
Variables de classe et d'instance Python
Les débutants en Python organisent des sortes de bulles
Trier par date en python
À propos de Python sort () et reverse ()
[Python] Traitement aléatoire (créer, sélectionner, trier)
objet perl et classe python partie 2.
Python
[Hikari-Python] Chapitre 09-03 Classe (Héritage)
Les mines terrestres cachées dans les variables de classe Python
Définitions de classe Python et gestion des instances
"La classe d'introduction Python la plus simple" modifiée
Lire des morceaux PNG en Python (édition de classe)
classe
[Python] Road to the Serpent (3) Classe Python
Trier les gros fichiers texte en Python
[Python] Tri Starlin à une ligne avec 50 caractères
Examiner la classe d'un objet avec python
objet perl et classe python partie 1.
Analyse de régression logistique Self-made avec python
classe
[Python] Hériter d'une classe avec des variables de classe
Trier
Lors de la spécification de plusieurs clés dans le tri python
Nouveautés de Python 3.9 (2) - Tri des graphes non circulés dirigés en Python
Créer un décorateur de fonction Python avec Class
[Introduction à Python] Comment utiliser la classe en Python?
[Mémo d'apprentissage] Bases de la classe par python