I have a list of object that looks like this.
hand = [ Card(10, 'H'), Card(2,'h'), Card(12,'h'), Card(13, 'h'), Card(14, 'h') ]
Card(10, 'H) here is not a tuple, but an object. I know how to sort this list if each item in the list was in a form of tuple, like this,
hand = sorted(hand, key = lambda x: x[0])
but I have no idea how to sort a list of objects. I want to sort my list by the first input value, which is the number in Card()
How can I do this?
Edit: Here's the definition of Card().
class Card(object):
RANKS = (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
SUITS = ('C', 'D', 'H', 'S')
def __init__(self, rank=12, suit='S'):
if (rank in Card.RANKS):
self.rank = rank
else:
self.rank = 12
if (suit in Card.SUITS):
self.suit = suit.upper()
else:
self.suit = 'S'
def __str__(self):
if (self.rank == 14):
rank = 'A'
elif (self.rank == 13):
rank = 'K'
elif (self.rank == 12):
rank = 'Q'
elif (self.rank == 11):
rank = 'J'
else:
rank = str(self.rank)
return rank + self.suit
def __eq__(self, other):
return (self.rank == other.rank)
def __ne__(self, other):
return (self.rank != other.rank)
def __lt__(self, other):
return (self.rank < other.rank)
def __le__(self, other):
return (self.rank <= other.rank)
def __gt__(self, other):
return (self.rank > other.rank)
def __ge__(self, other):
return (self.rank >= other.rank)
The sorted function can be used to sort the elements as desired, the frequency can be computed using the count function and removal of duplicates can be handled using the set function.
Using sort() We can use the sort() method to sort the set that we obtained in approach 2. This will also remove any duplicates, while preserving the order, but is slower than the dict. fromkeys() approach.
The idea is still the same. Just that you will be looking for a specific attribute in the class object.
For your card class, you could do something like this:
hand = [ Card(10, 'H'), Card(2,'h'), Card(12,'h'), Card(13, 'h'), Card(14, 'h') ]
Then you could do
sorted_cards = sorted(hand, key=lambda x: x.rank)
The output looks something like this:
>>> [card.number for card in sorted_cards]
[2, 10, 12, 13, 14]
This is the object-oriented approach. At a minimum, you should specify __eq__
and __lt__
operations for this to work. Then just use sorted(hand)
.
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __eq__(self, other):
return self.rank == other.rank and self.suit == other.suit
def __lt__(self, other):
return self.rank < other.rank
hand = [Card(10, 'H'), Card(2, 'h'), Card(12, 'h'), Card(13, 'h'), Card(14, 'h')]
hand_order = [c.rank for c in hand] # [10, 2, 12, 13, 14]
hand_sorted = sorted(hand)
hand_sorted_order = [c.rank for c in hand_sorted] # [2, 10, 12, 13, 14]
It's good practice to make object sorting logic, if applicable, a property of the class rather than incorporated in each instance the ordering is required. This way you can just call sorted(list_of_objects)
each time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With