sgrumo
sgrumo

Reputation: 665

Python3.5 Sorted Custom Compare doesn't work at expected

I'm trying to develop a simple custom compare for a list of strings to order. The list represents an array of cards and it's written like this :

['d10', 's2', 'c3', 'b5', 'c7', 'b2', 'b10', 'b7', 'c6', 's6']

Every string is represented with a char ('b','c','d','s'), the numeric values goes from 1 to 10 ( the FE requested me this, to me it'd be perfect if the values were from 0 to 9 ).

The problem: if I call the sort() function on the list it works fine except for the values with the 10 value. I think it considers 10 as a string and compares the first char which is 1 and compares to the others.

So I looked to custom sorting with sorted and cmp_to_key from functools library.

Here's what I wrote:

def distribute_hands(self):
    self.shuffle()
    hands = list(self.cards[p:p+SUIT_CARDS] for p in range(0, NUM_CARDS, SUIT_CARDS))
    for hand in hands: 
        hand = sorted(hand, key=cmp_to_key(self.custom_cmp))
    return hands

def custom_cmp(self, a, b):
    try:
        if (a[0] < b[0] or int(a[1]) < int(b[1]+b[2]) ):
            return 1 
        return 0
    except IndexError:
        if (a[0] < b[0] or int(a[1]) < int(b[1]) ):
            return 1 
        return 0

It's not well written 'cause I'm trying to find the best solution. The sort doesn't work at all and I can't understand why.

Python vers: 3.5.2

Upvotes: 0

Views: 98

Answers (2)

agubelu
agubelu

Reputation: 408

You can add a 0 to the number if it's not a 10, and then compare by keys directly:

hand = sorted(hand, key=lambda x: x if len(x) == 3 else x[0] + '0' + x[1])

Upvotes: 1

sjw
sjw

Reputation: 6543

Here's a much simpler solution:

cards.sort(key=lambda x: (x[0], int(x[1:])))
>>> ['b2', 'b5', 'b7', 'b10', 'c3', 'c6', 'c7', 'd10', 's2', 's6']

It works by sorting on a tuple form of the card, whereby the first element of the tuple is the first character of your string, and the second element of the tuple is the integer form of your second (and possibly 3rd in the case of '10') character(s) of your string.

Upvotes: 1

Related Questions