Python作业代码运行报错求助:随机抽牌程序出现KeyError:0异常
解决Python抽牌程序的KeyError及逻辑问题
错误原因分析
首先说你遇到的KeyError: 0——这是因为random.shuffle()只能用来打乱列表、元组这类序列类型,但你的my_cards是个字典。shuffle会试图通过索引(比如0)去访问元素,可字典是靠键来取值的,根本没有索引这一说,所以直接报错了。
除此之外,你的代码还有几个逻辑漏洞:
- 所有花色共享同一个
standard_cards列表:你给每个花色赋值的都是同一个列表对象,之后只要从任意花色移除一张牌,其他花色的对应牌也会消失,这完全不符合抽牌逻辑。 - 错误调用
my_cards.remove(chosen_card):my_cards是字典,根本没有remove()方法,你应该从对应花色的子列表里移除选中的牌。 - 变量
new_cards全程没用到,属于冗余代码。
修正后的代码
下面是修复了所有问题的版本,关键修改我都加了注释:
import random # 定义标准牌面 standard_cards = [2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K", "A"] # 每个花色单独复制一份牌面列表,避免共享引用导致的同步修改 my_cards = { "Hearts": standard_cards.copy(), "Diamonds": standard_cards.copy(), "Clubs": standard_cards.copy(), "Spades": standard_cards.copy() } picked_cards = [] for _ in range(3): # 先筛选出还有剩余牌的花色,避免抽到空花色 available_suits = [suit for suit in my_cards if my_cards[suit]] if not available_suits: print("没有剩余牌了!") break # 随机选一个有牌的花色 chosen_suit = random.choice(available_suits) # 从该花色的牌列表里随机抽一张 chosen_card = random.choice(my_cards[chosen_suit]) # 从对应花色的列表中移除这张牌,确保不会重复抽到 my_cards[chosen_suit].remove(chosen_card) # 把抽中的牌信息加入结果列表,注意把数字牌转成字符串 picked_cards.append(f"{chosen_suit} {str(chosen_card)}") print("User took these 3 cards:\n", picked_cards)
关键修改说明
- 独立复制列表:用
standard_cards.copy()给每个花色创建独立的牌面列表,这样修改一个花色的牌不会影响其他花色。 - 筛选可用花色:每次抽牌前先检查哪些花色还有牌,避免选中空列表导致的错误。
- 正确移除牌:从对应花色的子列表里移除选中的牌,而不是去操作字典本身。
- 简化字符串拼接:用f-string更简洁地组合花色和牌面,同时处理了数字牌的类型转换问题。
测试示例
运行后会得到类似这样的输出:
User took these 3 cards: ['Spades 7', 'Hearts A', 'Diamonds Q']
而且每张被抽中的牌都会从原集合中移除,不会出现重复抽取的情况。
内容的提问来源于stack exchange,提问作者tonyalmeida24
相关产品推荐
相关产品推荐

