Python self-made class sort

Motivation

Python has a sort function, including a list.sort () method and a sorted () function. I searched for sorting about my own class, but This is it! I couldn't find anything like that, so I'll leave it as a memorandum.

manner

According to Official, It can be done by specifying a Key function. Besides, it seems that it can be done by overloading the comparison operator of the class.

Example with comparison operator

I was making a card game after studying, In terms of how to sort from the playing card class At first I thought about overloading comparison operators. (C ++ programmer feeling)

If there was a playing card class with such a suit and numerical value (Part of the code is omitted)

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

Defines a comparison operator overload in the playing card class.

    def __lt__(self, other):
        """Comparison operator<"""
        return self.get_sort_number() < other.get_sort_number()

    def __gt__(self, other):
        """Comparison operator>"""
        return self.get_sort_number() > other.get_sort_number()

get_sort_number () defines the order of sorting by the size of the int number. It is an image that the smaller one comes first. In terms of suit, they are arranged in the order of spades, hearts, diamonds, clubs, and jokers. On get_sort_number (), by adding the number of the suit (Trump.SORT_ ~) and the number, I'm getting a number to sort.

    def get_sort_number(self):
        """Get an integer for sorting"""
        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
        #Returns a number with sorting and numbers added
        return n + self.number

By the way, I will put the sort numerical definition Since the number for each suit is 13, it is not necessary to set it to 20, but it is well separated by 20. If 13 of spades The number that can be taken by get_sort_number () is 0 + 13 and 13 If it's one of the hearts The number that can be taken by get_sort_number () is 20 + 1 and 21 It will be. Sorting is done by the size of this number.

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

We define a TrumpHand class that holds these cards together. (Not strictly necessary) You just have a Trump class in a list. When sorting, all you have to do is call the sort method of list. It sorts in ascending order without permission.

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

    def sort(self):
        """Sort your hand"""
        self.hand.sort()

Let's do this (The explanation of add and print is omitted ~~ You can imagine just by the name ~~)

    #Generate hand class(I just have it in the list)
    hand = trump_hand.TrumpHand()
    #Add 1 of Joker and Club and 1 of Spade to your hand
    hand.add(trump.Trump(trump.Trump.JOKER, 1))
    hand.add(trump.Trump(trump.Trump.CLUB, 1))
    hand.add(trump.Trump(trump.Trump.SPADE, 1))
    #Output the state before sorting
    hand.print()
    #sort
    hand.sort()
    #Output the sorted state
    hand.print()

This is the output before sorting. J1 (joker), C1 (club 1), S1 (spade 1) and the order added in the above code.

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

This is the output after sorting. S1 (1 of spades), C1 (1 of clubs), J1 (joker) And get_sort_number () in the exact order mentioned in the explanation.

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

problem

It wasn't a happy ending ...

Problem 1

Is it okay to use Trump comparison operators in sort order? The comparison operator can also be used to compare the strength of playing cards.

Problem 2

Depending on the rules of the game, the strength may change depending on the conditions, Or I want it to be easy for users to see, Isn't it difficult to be flexible with fixing?

Another way

This is where sorting using the Key function finally comes into play. ~~ Official has already been written so you don't have to look at this article ~~ ~~ But I didn't understand right away ~~

Quoted from the official

list.sort () and sorted () have key parameters. This is a parameter that specifies the function to be called for each element of the list before making the comparison. The key parameter must take a single argument and return the key used for sorting. This constraint allows for faster sorting, because the key function is called exactly once for each input record.

manner

You know that you should specify the function to be used for sorting in the Key function. The question is how to make a Key function,

If you look closely at the formula ** A common usage pattern is to sort an object consisting of several elements using one of the indexes as a key. ** **

This is likely to be get_sort_number () mentioned this time. Return a key consisting of a suit and a number element, have it sorted, that's it. When sorting in ascending order, if the number is low, it should be at the beginning, and if it is high, it should be at the end.

Rewrite the code by saying. ** (Note) It is recommended to specify trump.Trump.get_sort_number written below this method **

Before rewriting

    def sort(self):
        """Sort your hand"""
        self.hand.sort()

After rewriting (lambda expression)

    def sort(self):
        """Sort your hand"""
        self.hand.sort(key=lambda x: x.get_sort_number())

Specify the Key function with key = when calling the sort method. This time, get_sort_number () of the sort target (Trump class) is returned and used for sorting. As a side note, x is a Trump class.

Also, you don't need to overload the comparison operator mentioned above, let's erase it. I write it in a lambda expression, but if I write it normally, it looks like this. (Unverified)

#Key function definition somewhere
def get_sort_key(x):
    return x.get_sort_number()

    #rewrite sort(Specify Key function)
    def sort(self):
        """Sort your hand"""
        self.hand.sort(key=get_sort_key)

Recommended method

2020/04/19 18:00 postscript This is recommended because the program intention is clearer than @shiracamus (operation verified) Thank you for your comment

Before rewriting

    def sort(self):
        """Sort your hand"""
        self.hand.sort()

After rewriting (specify trump.Trump.get_sort_number in key function)

    def sort(self):
        """Sort your hand"""
        self.hand.sort(key=trump.Trump.get_sort_number)

This is what happens when you run the version that specifies the Key function.

Output before sorting

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

Output after sorting

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

Yes, it has the same output as the comparison operator. If you change the specification of the Key function according to the situation and specifications, you will be able to sort flexibly.

~~ Repentance ~~

~~ Python was just started a few days ago, so I'm sorry if there's something wrong ~~ ~~ The Trump class can be put into one variable by bit operation, but priority is given to clarity ~~ ~~ get_sort_number () You can write it shorter ~~

Recommended Posts

Python self-made class sort
[Python] Sort
Python # sort
[Python] class, instance
"Kanrika" python class
About python, class
Python class, instance
#Python basics (class)
python syslog wrapper class
Python class (Python learning memo ⑦)
case class in python
Bubble sort in Python
[Python] Class inheritance (super)
[python] class basic methods
[Python] Class inheritance, override
[Memo] Python3 list sort
python subprocess wrapper class
Python sort cheat sheet
Custom sort in Python3
[Python] Sort collection types
YOLO Python wrapper class
Class notation in Python
Python exception class list
x86 compiler self-made with python
Python: Class and instance variables
[Python] Loading multi-level self-made modules
Naturally sort Path in Python
C / C ++ programmer challenges Python (class)
Python basic dict sort order
Sort huge files with python
Python class member scope summary
python in mongodb in descending sort
Python class variables and instance variables
Python beginners organize bubble sort
Sort by date in python
About Python sort () and reverse ()
[Python] Random processing (create, select, sort)
How to write a Python class
perl objects and python class part 2.
Python
[Python of Hikari-] Chapter 09-03 Class (inheritance)
Landmines hidden in Python class variables
Python class definitions and instance handling
"The easiest Python introductory class" modified
Read PNG chunks in Python (class)
class
[Python] Road to snake charmer (3) Python class
Sort large text files in Python
[Python] One-liner Stalin sort with 50 characters
Examine the object's class in python
perl objects and python class part 1.
Logistic regression analysis Self-made with python
class
[Python] Inherit a class with class variables
sort
When specifying multiple keys in python sort
New in Python 3.9 (2)-Sort directed acyclic graphs in Python
Create a Python function decorator with Class
[Introduction to Python] How to use class in Python?
[Learning memo] Basics of class by python
Build a blockchain with Python ① Create a class