11

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)
6
  • 3
    You should implement an __eq__ or __gt__ or __lt__ method for that class so that you set what your comparison logic should be like when you compare instances of that class Commented Feb 11, 2018 at 1:27
  • definition of Card would help...what are those variables named in the class Commented Feb 11, 2018 at 1:30
  • @Ctznkane525 I just added the definition Commented Feb 11, 2018 at 1:32
  • What about your current class is not sorting? Commented Feb 11, 2018 at 1:36
  • x.rank is what you need...what's below...just needed to know whatever that property name was to answer it Commented Feb 11, 2018 at 1:37

2 Answers 2

25

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]
Sign up to request clarification or add additional context in comments.

Comments

12

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.