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.
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.
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
It wasn't a happy ending ...
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.
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?
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 ~~
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.
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)
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.
~~ 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