Sorting a list using sorted() by passing a list as the key argument

Mantis :

I've got a list which contains all cards from a standard 52 cards deck. I'm now wondering how i could sort these cards after their values, from Aces to Kings. My Idea was to use sorted() but I'm failing to grasp how I could pass the order of the list blueprint_deck as the key for the function.

My Script:

import random

Clubs = ["Clubs"]
Diamonds = ["Diamonds"]
Hearts = ["Hearts"]
Spades = ["Spades"]

blueprint_deck = [ "Ace", "2", "3", "4", "5", "6", "7",
                   "8", "9", "10", "Jack", "Queen", "King"]

deck = [i + " of " + j for i in blueprint_deck for j in Clubs + Diamonds + Hearts + Spades]

print(deck)

This would already return the deck sorted, but I want to know how I could achieve this order with a function after randomizing the list for example:

random_list = random.sample(deck, len(deck))
print(random_list)

What kind of function would I need to pass to the key argument of sorted() to achieve my goal? I've tried something like this:

def keyf(blueprint_deck):
    return blueprint_deck

print(sorted(random_list, key=keyf))

But that just seems to sort it in the default order of sorted().

Any help is appreciated, thank you!

Ivan Velichko :

I'd solve this task by assigning numerical weights for every card. Something like that:

weight = {"Ace": 1, "2": 2, "3": 3, "4": 4,
          "5": 5, "6": 6, "7": 7, "8": 8, 
          "9": 9, "10": 10, "Jack": 11,
          "Queen": 12, "King": 14}

def keyf(card):
    return weight[card.split()[0]]

print(sorted(random_list, key=keyf))

The function specified via key param is invoked for every element in the list. The idea is to assign some kind of rank to every element. However, since elements represented as plain text, we need to parse it first taking only the leftmost part.

UPD: Some extra explanation of the idea.

Imagine, you have a list of pairs. The nature of the list doesn't really matter, so let it consists of pairs like this [('jack', 11), ('ace', 1), ('queen', 12)]. If you want to sort the list by using only the second element from each pair (I call it a rank), you need to teach sorted() function to consider only at the second element (i.e. rank) while sorting the list:

lst = [('jack', 11), ('ace', 1), ('queen', 12)]
lst = sorted(lst, key=lambda c: c[1])

It's a common technique, at least in the Python world.

Now, getting back to the original task, you don't really have a list of pairs. Rather you have a list of strings of the following format "Ace of Clubs", "2 of Diamonds", etc. So, first, you need to convert every element to a pair by splitting the string on whitespace. Then, since you're interested in the rank, you need to map the left part (e.g. "Ace" or "2") to the numeric rank. For that, I use a dict mapping of such left parts to the corresponding numeric rank value.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=390686&siteId=1