通过将列表作为键参数,使用sorted()对列表进行排序

时间:2020-04-02 15:34:44

标签: python list sorting key

我有一个列表,其中包含标准52张卡组中的所有卡。我现在想知道如何对这些牌按照其价值从A到Kings进行排序。我的想法是使用sorted(),但是我无法掌握如何传递list blueprint_deck的顺序作为该函数的键。

我的脚本:

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)

这将返回已排序的卡片组,但是我想知道在将列表随机化后如何使用函数来实现此顺序,例如:

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

要实现我的目标,我需要将哪种函数传递给sorted()的关键参数? 我已经尝试过这样的事情:

def keyf(blueprint_deck):
    return blueprint_deck

print(sorted(random_list, key=keyf))

但这似乎只是按照sorted()的默认顺序对其进行排序。

感谢您的帮助,谢谢!

3 个答案:

答案 0 :(得分:1)

我将通过为每张卡分配数字权重来解决此任务。像这样的东西:

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))

将为列表中的每个元素调用通过key参数指定的函数。这个想法是给每个元素分配某种等级。但是,由于元素表示为纯文本,因此我们需要首先仅使用最左边的部分对其进行解析。

UPD:一些关于此想法的解释。

想象一下,您有一个配对列表。列表的性质并不重要,因此让它由像这样的[('jack', 11), ('ace', 1), ('queen', 12)]对组成。如果您想仅使用每对中的第二个元素对列表进行排序(我称其为等级),则需要教sorted()函数仅考虑第二个元素(即 rank ),同时对列表进行排序:

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

这是一种常见的技术,至少在Python世界中如此。

现在,回到原始任务,您实际上并没有列表对。而是具有以下格式的"Ace of Clubs""2 of Diamonds"等字符串列表。因此,首先,需要通过在空白处分割字符串将每个元素转换为一对。然后,由于您对排名感兴趣,因此需要将左侧部分(例如"Ace""2")映射到数字排名。为此,我将这些左侧部分的字典映射到相应的数字等级值。

答案 1 :(得分:1)

您要按值在列表中的位置进行排序; deck.index。这是一个示例:

suits = ["Clubs", "Diamonds", "Hearts", "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 suits]

test = ["8 of Spades", "9 of Spades", "Ace of Diamonds", "King of Hearts"]

print(test)
print(sorted(test, key = deck.index))

输出:

['8 of Spades', '9 of Spades', 'Ace of Diamonds', 'King of Hearts']
['Ace of Diamonds', '8 of Spades', '9 of Spades', 'King of Hearts']

答案 2 :(得分:0)

检查我的解决方案

orderTable = {"Ace": 0, "Jack": 10, "Queen": 11, "King": 12, "Clubs": 0, "Diamonds": 1,
  "Hearts": 2, "Spades": 3}

def cardOrder(card):
  (f,x,s) = card.split()
  n = orderTable[f] if f in orderTable else int(f) - 1
  return n * 4 + orderTable[s]

def sort_deck(deck_list):
  sorted_list = list(range(13 * 4))
  for card in deck_list: 
    sorted_list[cardOrder(card)] = card;
  return sorted_list

测试

print(deck, end="\n---Shuffled deck---\n")
print(random_list, end="\n---Ordered once again---\n")
print(sort_deck(random_list))

输出

['Ace of Clubs', 'Ace of Diamonds', 'Ace of Hearts', 'Ace of Spades', '2 of Clubs',
 '2 of Diamonds', '2 of Hearts', '2 of Spades', '3 of Clubs', '3 of Diamonds',
 '3 of Hearts', '3 of Spades', '4 of Clubs', '4 of Diamonds', '4 of Hearts',
 '4 of Spades', '5 of Clubs', '5 of Diamonds', '5 of Hearts', '5 of Spades',
 '6 of Clubs', '6 of Diamonds', '6 of Hearts', '6 of Spades', '7 of Clubs',
 '7 of Diamonds', '7 of Hearts', '7 of Spades', '8 of Clubs', '8 of Diamonds',
 '8 of Hearts', '8 of Spades', '9 of Clubs', '9 of Diamonds', '9 of Hearts',
 '9 of Spades', '10 of Clubs', '10 of Diamonds', '10 of Hearts', '10 of Spades',
 'Jack of Clubs', 'Jack of Diamonds', 'Jack of Hearts', 'Jack of Spades',
 'Queen of Clubs', 'Queen of Diamonds', 'Queen of Hearts', 'Queen of Spades',
 'King of Clubs', 'King of Diamonds', 'King of Hearts', 'King of Spades']
---Shuffled deck---
['9 of Spades', '5 of Hearts', 'King of Clubs', '9 of Diamonds', '6 of Diamonds',
 'Ace of Spades', '5 of Diamonds', '3 of Clubs', '5 of Spades', '7 of Hearts',
 'Queen of Spades', '4 of Hearts', 'Jack of Spades', '7 of Spades', '4 of Spades',
 'King of Hearts', 'King of Spades', 'Jack of Clubs', '4 of Clubs', '3 of Hearts',
 '2 of Clubs', '2 of Hearts', 'Queen of Hearts', 'Ace of Diamonds', 'Jack of Hearts',
 '10 of Clubs', '8 of Diamonds', '7 of Diamonds', '10 of Hearts', '10 of Diamonds',
 'King of Diamonds', '5 of Clubs', 'Ace of Hearts', 'Ace of Clubs', '4 of Diamonds',
 '3 of Spades', 'Queen of Diamonds', '2 of Spades', '6 of Spades', '9 of Clubs',
 '8 of Clubs', 'Jack of Diamonds', '3 of Diamonds', '10 of Spades', '2 of Diamonds',
 '7 of Clubs', '6 of Clubs', '8 of Spades', 'Queen of Clubs', '9 of Hearts',
 '6 of Hearts', '8 of Hearts']
---Ordered once again---
['Ace of Clubs', 'Ace of Diamonds', 'Ace of Hearts', 'Ace of Spades', '2 of Clubs',
 '2 of Diamonds', '2 of Hearts', '2 of Spades', '3 of Clubs', '3 of Diamonds',
 '3 of Hearts', '3 of Spades', '4 of Clubs', '4 of Diamonds', '4 of Hearts',
 '4 of Spades', '5 of Clubs', '5 of Diamonds', '5 of Hearts', '5 of Spades',
 '6 of Clubs', '6 of Diamonds', '6 of Hearts', '6 of Spades', '7 of Clubs',
 '7 of Diamonds', '7 of Hearts', '7 of Spades', '8 of Clubs', '8 of Diamonds',
 '8 of Hearts', '8 of Spades', '9 of Clubs', '9 of Diamonds', '9 of Hearts',
 '9 of Spades', '10 of Clubs', '10 of Diamonds', '10 of Hearts', '10 of Spades',
 'Jack of Clubs', 'Jack of Diamonds', 'Jack of Hearts', 'Jack of Spades',
 'Queen of Clubs', 'Queen of Diamonds', 'Queen of Hearts', 'Queen of Spades',
 'King of Clubs', 'King of Diamonds', 'King of Hearts', 'King of Spades']