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

Python菜谱匹配代码报错TypeError: unhashable type: 'set'求助

解决你的食材匹配菜品问题

嘿,我看到你的问题啦——那个TypeError确实是因为集合不能当字典的键用。咱们一步步来捋清楚怎么修:

错误原因分析

你写的match = set([iP]) & set(allRec)会得到一个集合(比如{(0,1,3)}),而字典allRecNames的键是元组,集合属于不可哈希类型,自然没法用来查字典,所以就报错了。其实你已经通过if iP in allRec确认了用户选的食材组合在菜谱里,完全不需要用集合交集来多此一举~

修复后的代码

直接把那几行判断匹配的代码简化,用iP这个元组直接去字典里取对应的菜名就行,同时我还优化了输入提示,让用户更清楚该选什么:

# all ingredients, represented by numbers: 0= empty selection 1=rice 2=spice 3=vegetable
allIng = [0,1,2,3]
# 食材名称映射,方便输入提示用
ingNames = {0: "empty selection", 1: "rice", 2: "spice", 3: "vegetable"}

#Each individual recipe(r)
# Veggie Rice Balls
r1 = (0,1,3)
# Curry Rice
r2 =(0,1,2)
# Herb Sauté
r3 = (0,2,3)
# Vegetable Curry
r4 = (1,2,3)
# all recipes on one list
allRec = [r1,r2,r3,r4]
allRecNames = {(0,1,3): 'Veggie Rice Balls', (0,1,2): 'Curry Rice', (0,2,3): 'Herb Sauté', (1,2,3): 'Vegetable Curry'}

#ingredients picked
iP = []
#ingredient count
iC = 1
#User given option to pick up to 3 ingredients
print(f"可选食材:{', '.join([f'{num}={name}' for num, name in ingNames.items()])}")
while iC <= 3:
    try:
        pitem = int(input(f"请选择第{iC}种食材(最多选3种):"))
        if pitem in allIng:
            iP.append(pitem)
            print(f"已选食材:{[ingNames[item] for item in iP]}")
            iC += 1
        else:
            print("输入错误,请从可选食材里选哦")
    except ValueError:
        print("请输入数字哦")

#sort list并转成元组
iP.sort()
iP = tuple(iP)

#compare iP to allRec looking for matches
if iP in allRec:
    # 直接用iP作为键取菜名
    print(f"匹配成功!你可以做:{allRecNames[iP]}")
else:
    print("没有找到对应的菜谱哦")

额外优化点(可选)

如果想避免用户重复选同一种食材,可以在if pitem in allIng:后面再加个判断:and pitem not in iP,这样用户就不能重复选啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:42:41