Python列表元素分配对象属性异常:发牌后所有玩家手牌相同
卡牌分发代码问题分析
问题场景
随机向多名玩家分发52张编号卡牌,以下是编写的Python代码及运行结果:
分发卡牌的代码
import random def deal(players): deck = [x for x in range(1,53)] random.shuffle(deck) internalObject = { 'cards': [], 'score': 0} starting = dict.fromkeys(players, internalObject) deckHasCards = True while (deckHasCards): for player in players: if deck == []: deckHasCards = False break card = deck.pop() starting[player]['cards'].append(card) card = 0 return starting def main(): hands = deal(['Jack', 'Jill']) print(hands)
运行输出
{ 'Jack': {'cards': [35, 31, 20, 15, 18, 26, 51, 19, 37, 21, 10, 44, 4, 9, 14, 52, 49, 29, 43, 5, 41, 47, 40, 7, 3, 25, 11, 22, 23, 48, 2, 32, 13, 30, 6, 16, 38, 34, 45, 36, 39, 28, 50, 24, 46, 42, 27, 1, 33, 17, 8, 12], 'score': 0}, 'Jill': {'cards': [35, 31, 20, 15, 18, 26, 51, 19, 37, 21, 10, 44, 4, 9, 14, 52, 49, 29, 43, 5, 41, 47, 40, 7, 3, 25, 11, 22, 23, 48, 2, 32, 13, 30, 6, 16, 38, 34, 39, 28, 50, 24, 46, 42, 27, 1, 33, 17, 8, 12], 'score': 0} }
问题
所有玩家最终手牌相同,请问代码存在什么问题?为何Python会给所有玩家分配同一张牌而非当前循环选中的玩家?
问题分析与修复
核心问题
问题出在starting = dict.fromkeys(players, internalObject)这一行:
- Python的
dict.fromkeys()方法会把同一个对象的引用赋值给字典里的所有键。这里的internalObject是一个字典,所有玩家对应的value都是指向这个字典的指针,并非每个玩家拥有独立的字典实例。 - 所以当你执行
starting[player]['cards'].append(card)时,不管循环到哪个玩家,都是在修改同一个cards列表,最终所有玩家的手牌自然完全相同。
修复代码
把创建玩家字典的方式改成字典推导式,为每个玩家生成独立的字典对象:
import random def deal(players): deck = [x for x in range(1,53)] random.shuffle(deck) # 用字典推导式为每个玩家创建独立的卡牌字典 starting = {player: {'cards': [], 'score': 0} for player in players} deckHasCards = True while deckHasCards: for player in players: if not deck: deckHasCards = False break card = deck.pop() starting[player]['cards'].append(card) return starting def main(): hands = deal(['Jack', 'Jill']) print(hands)
这样每个玩家都会拥有自己独立的cards列表,分发卡牌时各自累加,就不会出现手牌相同的问题了。
内容的提问来源于stack exchange,提问作者M Towseef Hossain
相关产品推荐
相关产品推荐

