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

如何将list(list(tuple))转换为list(set(tuple))解决unhashable类型报错

报错原因
  • 触发TypeError: unhashable type的核心原因是:原有代码生成的单副手牌是list类型,列表属于可变对象,本身不可哈希,无法被存入集合;同时原有递归逻辑全程生成嵌套列表结构,和要求的list[set[tuple]]目标结构不匹配。
  • 定义的类型别名Hand = set[tuple[str, str]]要求单个手牌为存储卡牌元组的集合,但原有代码的递归终止条件、元素拼接逻辑都是基于列表实现,完全没有用到集合类型。
无依赖修复方案

不需要导入任何模块,只需要修改all_matches函数的两处逻辑即可:

  1. 递归终止条件(num == 0时),将原来返回的空列表[[]]改为返回空集合[set()],对齐集合类型的手牌结构。
  2. 替换原来的列表拼接逻辑,每次生成新手牌时新建集合副本,加入当前选中的卡牌,避免修改递归链路中复用的集合对象,最终得到的每个手牌都是合法的set结构。

修复后的完整可运行代码:

Hand = set[tuple[str, str]]


def all_card():  # 52 cards
    rank: list[str] = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
    suit: list[str] = ['Club', 'Diamond', 'Heart', 'Spade']
    my_card = []
    for i in rank:
        for j in suit:
            my_card.append((i, j))
    return my_card


def all_matches(cards, num):
    if num == 0:
        return [set()]
    L = []
    for i in range(0, len(cards)):
        first = cards[i]
        rem = cards[i + 1:]
        all_comb = all_matches(rem, num - 1)
        for comb in all_comb:
            # 新建集合副本,避免修改原有递归结果
            new_hand = set(comb)
            new_hand.add(first)
            L.append(new_hand)
    print(len(L))
    return L


def all_hands() -> list[Hand]:  # 2,598,960
    my_card = all_card()
    return all_matches(my_card, 5)


print(all_hands())
验证说明
  • 代码运行后会打印组合总数2598960,和5张牌的德州扑克手牌总数完全一致。
  • 最终返回结构为list[set[tuple[str, str]]],符合要求的list(set(tuple))结构,集合内存储的卡牌元组为不可变类型,不会再触发不可哈希的报错。
  • 全程未使用任何import语句,满足课程要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:48:16