You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现先按卡牌类型再按卡牌值对Python卡牌列表排序?

问题描述

需要实现先按卡牌类型、再按卡牌值对卡牌列表排序,预期示例:2 clubs , 3 clubs , 6 clubs , 5 heart, 10 heart……。尝试使用lambda函数作为sorted的key但未得到预期结果,请求帮助。

现有代码如下:

from enum import Enum
import random

type=Enum('type','Heart Diamond Club Spade')
value=Enum('value','2 3 4 5 6 7 8 9 10 J Q K A')

class Card():
    def __init__(self,type,value) :
        self.card_type=type
        self.card_value=value

    def __str__(self) :
        txt=str(self.card_value.name)+' '+str(self.card_type.name)
        return txt

    def __eq__(self, __o: object) -> bool:
        if self.card_type==__o.card_type and self.card_value==__o.card_value:
            return True
        else:
            return False

    def __lt__(self,__o:object) -> bool:
        if self.card_type==__o.card_type and int(self.card_value.value)<int(__o.card_value.value):
            return True
        else:
            return False

    def __gt__(self,__o:object) -> bool:
        if self.card_type==__o.card_type and int(self.card_value.value)>int(__o.card_value.value):
            return True
        else:
            return False

def deal(deck,cardNum):
    cardlist=list()
    for i in range(cardNum):
        c=random.choice(deck)
        deck.remove(c)
        cardlist.append(c)
    #sorted(cardlist,key=lambda ) # My problem is here :(
    return cardlist
解决方案

问题出在两个核心点:一是Card类的比较方法(__lt__/__gt__)仅处理同类型卡牌的比较,不同类型时无排序逻辑;二是sorted函数未正确设置排序规则。下面提供两种修复方式:

方式一:修复Card类的比较方法

让__lt__方法先比较卡牌类型的枚举值,再比较卡牌值的枚举值,Python内置排序会自动依据该逻辑完成排序:

def __lt__(self, __o: object) -> bool:
    # 先按类型排序,类型相同时按卡牌值排序
    if self.card_type.value != __o.card_type.value:
        return self.card_type.value < __o.card_type.value
    return self.card_value.value < __o.card_value.value

无需单独实现__gt__,Python会自动通过__lt__推导反向比较逻辑。

修改后在deal函数中直接调用sorted:

cardlist = sorted(cardlist)

方式二:使用sorted的key参数(无需修改类方法)

如果不想改动Card类的原有逻辑,可直接给sorted指定元组类型的key——元组首元素为卡牌类型枚举值,次元素为卡牌值枚举值,排序时会先按类型、再按值排序:

cardlist = sorted(cardlist, key=lambda card: (card.card_type.value, card.card_value.value))

完整优化代码示例

以下是结合方式一的完整代码,同时将type/value改为CardType/CardValue避免与Python内置函数名冲突:

from enum import Enum
import random

CardType = Enum('CardType', 'Heart Diamond Club Spade')
CardValue = Enum('CardValue', '2 3 4 5 6 7 8 9 10 J Q K A')

class Card():
    def __init__(self, card_type, card_value):
        self.card_type = card_type
        self.card_value = card_value

    def __str__(self):
        return f"{self.card_value.name} {self.card_type.name}"

    def __eq__(self, __o: object) -> bool:
        return self.card_type == __o.card_type and self.card_value == __o.card_value

    def __lt__(self, __o: object) -> bool:
        if self.card_type.value != __o.card_type.value:
            return self.card_type.value < __o.card_type.value
        return self.card_value.value < __o.card_value.value

def deal(deck, card_num):
    card_list = []
    for _ in range(card_num):
        card = random.choice(deck)
        deck.remove(card)
        card_list.append(card)
    # 执行排序
    card_list = sorted(card_list)
    return card_list

# 测试功能
if __name__ == "__main__":
    # 生成完整牌堆
    full_deck = [Card(ctype, cval) for ctype in CardType for cval in CardValue]
    # 发10张牌并排序
    dealt_cards = deal(full_deck, 10)
    # 打印结果
    for card in dealt_cards:
        print(card)

内容的提问来源于stack exchange,提问作者Stefano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:27:26