使用变量从列表中删除项目

时间:2019-01-03 23:48:44

标签: python list

我正在针对机器人构建扑克游戏,并在列表中列出了卡号。当给玩家或机器人一张卡时,我显然需要从列表中删除该卡,以免再次发卡。

def dealPlayer():
    cardSuit = random.randrange(1, 5) #Decide card suit#
    if cardSuit == 1:
        cardNum = random.randrange(0, 13) #Decide card num#
        if cardNum == 11: #Make sure it prints the name not position in list#
            cardNum = "jack"
        elif cardNum == 12:
            cardNum = "queen"
        elif cardNum == 13:
            cardNum = "king"
        elif cardNum == 0:
            cardNum = "ace"
        print ("Your first card is the", cardNum, "of clubs.")
        del Clubs[cardNum] #Problem#
        print(Clubs) #Debugging#

我遇到的问题在倒数第二行。这是它引起我的错误:

TypeError: list indices must be integers or slices, not str

4 个答案:

答案 0 :(得分:0)

尝试使用以下代码作为完整代码:

def dealPlayer():
    cardSuit = random.randrange(1, 5) #Decide card suit#
    if cardSuit == 1:
        cardNum = random.randrange(0, 13) #Decide card num#
        if cardNum == 11: #Make sure it prints the name not position in list#
            cardNum_ = "jack"
        elif cardNum == 12:
            cardNum_ = "queen"
        elif cardNum == 13:
            cardNum_ = "king"
        elif cardNum == 0:
            cardNum_ = "ace"
        print ("Your first card is the", cardNum_, "of clubs.")
        del Clubs[cardNum]
        print(Clubs)

稍微更改变量名称使其起作用。

答案 1 :(得分:0)

每当cardNum随机值为0、11、12或13时,您都将为cardNum变量分配一个字符串值。

在将Clubs变量设置为cardNum之后访问"king"列表时,实际上是在做以下事情:

Clubs["king"]  # Invalid access (str as list index)

您只能访问整数形式的列表索引(0、1、2等),并且只能访问列表中填充的那些索引(有效索引)。

由于分配字符串值的原因是为了打印,因此您应该只使用另一个变量来存储卡名,就像这样:

def dealPlayer():
    cardSuit = random.randrange(1, 5) #Decide card suit#
    if cardSuit == 1:
        cardNum = random.randrange(0, 14) # Decide card number [0,14), upper exclusive
        if cardNum == 11:
            cardName = "jack"
        elif cardNum == 12:
            cardName = "queen"
        elif cardNum == 13:
            cardName = "king"
        elif cardNum == 0:
            cardName = "ace"
        else:
            cardName = cardNum

        print ("Your first card is the", cardName, "of clubs.")
        Clubs.remove(cardNum)

那么您将没有任何问题,因为cardNum保持不变并且是整数。另请注意,更改为Clubs.remove(cardNum)。这是从列表中删除项目的正确方法。

编辑

这里的逻辑也是有缺陷的:从列表中删除“三个俱乐部”(在您的情况下,索引为3的对象,如果0为ace),该列表将然后缩短一张牌,列表中“三家具乐部”之后的任何一张牌都将降低一个索引。这意味着,如果您然后期望索引4上的对象是“四家具乐部”,则实际上将是“五家具乐部”,因为所有东西都相减了一个。您需要更改设计以解决此问题。

答案 2 :(得分:0)

首先,cardNum是一个字符串。你可以做

del Clubs[int(cardNum)]

但这不会得到您想要的结果,它将从列表中删除索引cardNum。 您想要的是:

Clubs.remove(cardNum)

所以del按索引删除 list.remove()按项目删除

答案 3 :(得分:0)

问题是您在某些情况下会将cardNum转换为字符串,因此答案是停止这样做。就个人而言,我会将卡命名为单独的方法:

def cardName(cardNum):
    if cardNum == 11:
        return "jack"
    elif cardNum == 12:
        return "queen"
    elif cardNum == 13:
        return "king"
    elif cardNum == 0:
        return "ace"
    return str(cardNum)


def dealPlayer():
    cardSuit = random.randrange(1, 5) #Decide card suit#
    if cardSuit == 1:
        cardNum = random.randrange(0, 14) #Decide card num#
        print ("Your first card is the", cardName(cardNum), "of clubs.")
        del Clubs[cardNum]

注意:您的random.randrange(0, 13)是错误的,它不包括13。您要么想使用random.randrange(0, 14),要么想使用random.randint(0, 13)

我认为您还应该考虑使用卡组而不是列表作为牌手和副牌,因为列表的去除是O(1)vs O(n)。

此外,您对事物的跟踪方式也不理想。如果Clubs是一组可用的卡片,那么您实际上应该从该卡片集中选择下一张卡片。像这样:

cardNum = random.choice(Clubs)

当然,您也需要注意西服的选择。有可能没有剩余的俱乐部,在这种情况下,您需要选择其他方式。我认为,理想情况下,您应该只保留一个套牌,而不是每套西装都单独列出。您可以在这里使用元组来帮助您:

deck = set([])
for suit in ["clubs", "spades", "hearts", "diamonds"]:
    for i in range(14):
        deck.add((suit, i))

然后使用deck随机选择,从random.sample(deck, 1)[0]中删除每张卡:

>>> random.sample(deck, 1)[0]
('spades', 9)

(如果您可以在此处使用random.choice(),但它不接受集合,那将是很好的选择