"Pop index out of range" 一副纸牌

"Pop index out of range" for deck of cards

我目前拥有的是构建一副纸牌、洗牌以及从该副牌构建一手牌的代码。

from random import randint

def make_deck():
    deck = []
    for suit in suits:
        for rank in ranks:
           deck.append((suit,rank))
    return deck

suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']

deck = make_deck() #list of cards

def shuffle(deck):
    for k in range(100): # do it 100 times
        card = deck.pop(randint(0,51))
        deck.append(card)

def make_hand():
    hand = []
    for k in range(2):
        card = deck.pop(randint(0,51))
        hand.append(card)
    return hand

hand = make_hand()

当我 运行 程序时,打印 deck 会给我我喜欢的纸牌列表,然后当我尝试洗牌时,我收到一条错误消息,指出 pop 索引超出范围。不太确定为什么它会超出索引,因为范围 (0,51) 代表一副牌中的所有 52 张牌。

当我尝试使用 make_hand() 函数时出现同样的错误,但并非总是如此。我是否错误地使用了 pop 方法?我必须更改什么才能使 shuffle 功能正常工作,并且 hand 总是 return 两张不同的牌?

pop 通过从列表中删除项目来改变列表。因此,列表的长度将变得小于 52 并且最终会抛出错误。而不是 51,每次使用列表的长度 len(deck)

对于改组,您还可以使用库 random:

中的函数 shuffle
from random import shuffle
## later in the code 
shuffle(deck)

这样写比较安全

card = deck.pop(randint(0,len(deck)-1))

尽管将该值保存在某处会更快。

但这也说明了一个问题,就是你的套牌有问题。您是否正确格式化了套牌创建中的循环?您创建的卡片可能少于 52 张,因此当您在高端生成整数时,您会发现该错误。如果它偶尔发生在 make_hand 中(你迭代两次)并且经常发生在 shuffle 中(你迭代 100 次),这似乎也很可能。

如果您打算在发牌后洗牌,那么您肯定需要使用 len() 或以其他方式跟踪牌组大小。甚至在 make_hand 函数中,你正在弹出一张卡片,然后仍然尝试从大小为 52 的列表中抽取,即使你已经取出一张卡片。

make_hand中,您从牌组中取出 2 张牌。第一个总是会成功,但第二个必须使用仅包含 51 张牌的套牌,同时仍有 52 分之一的机会尝试 pop(52),但会失败。

我无法用 shuffle 函数重现相同的错误,除非我首先将 make_hand 中使用过的套牌传递给它,所以我假设这就是你所做的嗯。

为了确定,您可以在两个函数中使用 randint(0, len(deck)-1)