-2

I'm making a game in python with a deck of cards. I have an array of the cards I've created, and shuffled. I would like to be able to sort this array, both by value: {2,3,4,5,6,7,8,9,10,J,Q,K,A} and by their suit and corresponding values - same order of values. I have previously used the sort and sorted methods, however am unsure how to do this with an array of objects as I am getting the output: TypeError: 'Card' object is not subscriptable. How would I go about creating these sorting algorithims?

I have tried the following: self.cards.sort(key=lambda x: x.value) This sorts it the the order: {10,2,3,4,5,6,7,8,9,A,J,Q,K} I understand the alphabetical order this is sorted in, however am unsure why 10 is the first item listed.

I have also tried things like: values=dict(zip('23456789TQKA',range(2,15))) but this seems to give me the error I have previously talked about.

Any help would be apricated! Thanks!

This is the code I currently have:

from random import randint

class Card:
def __init__(self, suit, value):
    self.suit = suit
    self.value = value

def show(self):
    print("{} - {}".format(self.value, self.suit))

class Deck:
size = 52
def __init__(self):
    self.cards = []
    self.build()

def build(self):
    for s in ["C", "D", "H", "S"]:
        for v in ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]:
            self.cards.append(Card(s, v))

def show(self):
    for c in self.cards:
        c.show()

def shuffle(self):
    for i in range(self.size-1, 0, -1):
        r = randint(0, i + 1)
        self.cards[i], self.cards[r] = self.cards[r], self.cards[i]

#Sorting will go here

deck = Deck()
print("After creating The Deck")
deck.show()
deck.shuffle()
print("After Shuffling The Deck: ")
deck.show()
deck.mergeSort()
print("After the merge Sort")
deck.show()
  • 1
    Why? Because the character `"1"` is less than the character `"2"`. You don't ever need to sort a deck of cards in a game. Your `values` concept is the right way to solve this problem, if you really need it. That lets you create a sort key in your desired order. – Tim Roberts Sep 17 '22 at 00:56
  • Welcome to Stack Overflow. "however am unsure how to do this with an array of objects as I am getting the output: TypeError: 'Card' object is not subscriptable." **Where**? From *what part of the code*? Please read [ask] and [mre] and make sure to show [complete](https://meta.stackoverflow.com/questions/359146) error messages. Note well that this is not a debugging service. Also, please make sure of the indentation of your code when posting. If you indent the code in order to get a code block, you must give **each** line an **extra** four space of indentation. – Karl Knechtel Sep 17 '22 at 01:04
  • 1
    "self.cards.sort(key=lambda x: x.value)" This is the appropriate approach. The next step is to think of a better function to use for the `key`. It will need to be more complex. Note that you can use a function defined with `def` for this as well; `lambda` is **just** a way of defining simple functions (in-line, and without naming them), and has **nothing to do with** the `sort` function. – Karl Knechtel Sep 17 '22 at 01:06
  • "Any help would be apricated! Thanks!" Please note well that this is **not a discussion forum**. We [do not offer](https://meta.stackoverflow.com/questions/284236/) "any help", and [do not want](https://meta.stackoverflow.com/questions/288160/no-thanks-damn-it) your thanks. – Karl Knechtel Sep 17 '22 at 01:07

2 Answers2

1

You're trying to sort strings. When sorting strings it starts with the first character, and then moves on to the next character if necessary. 'AZ' goes before 'B' because an 'A' is less than 'B'. The same thing happens when you have a '10'. It starts by comparing the '1' which goes before everything else in your deck of cards. If you only had integers you would be able to use my_list.sort(key=int), but when you have a mix of integers and characters you need to do something else. Natural sort is one way of solving this issue, however, there is a simpler approach we can use since we have a small finite number of items that we are sorting. What we can do instead is create a list that has all of the card values in the order that we want them to be in, and then we refer back to that list in the key function passed to sort, like so:

def sort_cards(cards):
    card_order = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
    return sorted(cards, key=lambda card: card_order.index(card.value))

my_cards = ['10', '5', 'A', '7', 'K']
print(sort_cards(my_cards))

Outputs

['5', '7', '10', 'K', 'A']

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
-1

you can try this

b=[2,3,4,5,6,7,8,9,10,'J','Q','K','A']
sorted(b, key=lambda i: (isinstance(i, int), i), reverse=True)

print(sorted(b, key=lambda i: (isinstance(i, int), i)))
Bhar Jay
  • 184
  • 8