一副牌的“流行指数超出范围”

问题描述 投票:0回答:3

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

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
会给我我喜欢的卡片列表,然后当我尝试洗牌时,我收到一条错误消息,指出弹出索引超出范围。不太清楚为什么它会超出索引,因为范围 (0,51) 代表这副牌的所有 52 张牌。

当我尝试使用

make_hand()
函数时,会出现相同的错误,但并非总是如此。我是否错误地使用了
pop
方法?我必须更改什么才能使
shuffle
功能正常工作并且
hand
始终从牌组中返回两张不同的牌?

python playing-cards
3个回答
4
投票

pop
通过从列表中删除项目来改变列表。因此,列表的长度将变得小于
52
并且最终会抛出错误。每次都使用列表的长度,而不是
51
对于洗牌,您还可以使用库中的函数 

len(deck)

shuffle
:
random



2
投票

from random import shuffle ## later in the code shuffle(deck)

尽管如果将该值保存在某处,速度会更快。 

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

如果您的目的是在发牌后洗牌,那么您肯定需要使用 len() 或以其他方式跟踪牌组的大小。即使在 make_hand 函数中,您也会弹出一张卡,然后仍然尝试从大小为 52 的列表中绘制,即使您已经取出了一张卡。


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

中,您从牌堆中取出2张牌。第一个总是会成功,但第二个必须使用仅包含 51 张牌的牌组,而仍然有 52 分之一的机会尝试

make_hand
,这会失败。

我无法使用

pop(52)

函数重现相同的错误,除非我先向它传递一个已在

shuffle
中使用过的牌组,所以我假设这也是您所做的。

为了确定,您可以在这两个函数中使用

make_hand

    

© www.soinside.com 2019 - 2024. All rights reserved.