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

Python纸牌游戏开发中字典索引列表触发KeyError问题求助

问题排查与修复方案

1. KeyError触发的核心原因

你在remove_card函数中重复做了索引转换,直接导致查询字典失败:

  • 在choose_card函数中,你已经通过change字典把输入的字母转成了0-7的数字索引,赋值给了v1、v2两个参数
  • 到了remove_card函数里,你又把已经是数字的v1、v2当成字母去查change字典,而change字典只有'A'-'H'的字符串键,没有数字键,自然就触发KeyError。

2. 其他需要修复的逻辑错误

  • 无效嵌套问题:你定义piles的时候把每个牌堆又额外套了一层列表:piles = [[pile1], [pile2], ...],完全冗余,直接改成piles = [pile1, pile2, pile3, pile4, pile5, pile6, pile7, pile8]即可,否则会导致后续索引取值多写不必要的层级,容易出问题。
  • 函数调用不匹配:spill()函数里调用的是velg_kort(),但你实际定义的处理输入的函数是choose_card(),直接运行会触发NameError,要把调用处改成choose_card()。
  • 执行顺序错误:你在定义choose_card、remove_card两个函数之前就调用了spill(),运行时会找不到这两个函数,要把spill()的调用移到所有函数定义之后。
  • 输入大小写兼容问题:如果用户输入小写的a、b等字符,你的change字典只有大写键,也会触发KeyError,建议把输入的字符转大写后再查询字典,同时增加非法字符校验。
  • 多余的重复赋值:spill()执行完你又重新给piles赋值了一次,完全没有必要,可以删掉。

3. 修复后的核心代码示例

import random
SPAR_SYMBOL = '\u2660'
RUTER_SYMBOL = '\u2666'
KLØVER_SYMBOL = '\u2663'
HJERTER_SYMBOL = '\u2665'
kortstokk = []

pile1 = []
pile2 = []
pile3 = []
pile4 = []
pile5 = []
pile6 = []
pile7 = []
pile8 = []
for kort in range(7, 15):
    kortstokk.append(f'\u2660{kort}')
    kortstokk.append(f'\u2666{kort}')
    kortstokk.append(f'\u2663{kort}')
    kortstokk.append(f'\u2665{kort}')

# 修正piles定义,去掉多余嵌套
piles = [pile1, pile2, pile3, pile4, pile5, pile6, pile7, pile8]

def del_ut():
    random.shuffle(kortstokk)
    # 简化冗余的if判断,直接用索引操作牌堆
    for j in range(4):
        for i in range(8):
            piles[i].append(kortstokk.pop())

def tap():
    pass

def seier():
    pass

def lagre():
    pass

def last_inn():
    pass

def choose_card():
    global piles
    cards = input("choose two piles of cards: ").upper() # 转大写兼容小写输入
    change= {'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7}
    # 增加输入合法性校验,避免非法字符触发KeyError
    if len(cards) == 2 and cards[0] in change and cards[1] in change:
        v1 = change[cards[0]]
        v2 = change[cards[1]]
        remove_card(v1, v2)
    else:
        print("Invalid input.")

def remove_card(v1, v2):
    global piles
    # 去掉多余的change查询,直接用传入的数字索引
    if v1 != v2 and piles[v1][-1][-1] == piles[v2][-1][-1]:
        piles[v1].pop(-1)
        piles[v2].pop(-1)
        # 可增加判断所有牌堆为空时触发胜利逻辑
        if all([len(p) == 0 for p in piles]):
            seier()

def spill():
    del_ut()
    while True:
        # 取值简化,去掉多余的嵌套层级
        print("A: ", piles[0][-1])
        print("B: ", piles[1][-1])
        print("C: ", piles[2][-1])
        print("D: ", piles[3][-1])
        print("E: ", piles[4][-1])
        print("F: ", piles[5][-1])
        print("G: ", piles[6][-1])
        print("H: ", piles[7][-1])
        choose_card() # 修正函数名调用

# spill()调用移到所有函数定义之后
spill()

关于问题表述的建议

你的表述非常清晰,已经把需求、预期效果、遇到的问题都讲清楚了,还附上了完整可复现的代码,完全符合技术提问的要求,不需要调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:24:06