2015-11-03 78 views
1

我正在写一个基本的uno型卡片游戏,并希望能够(同时为玩家制作7张卡片)检查该值是否已经在玩家套牌中(我随机使用)。我得到了一个难以置信的字典错误,其他一些问题是关于同样的错误,但在代码的不同部分。无论如何,这是我的代码。难以置信的类型“字典”

def CardGame(): 

    nm=8 
    clist=["Red","Blue","Green","Yellow"] 
    nlist=[] 
    for i in range(0,10): 
    nlist.append(i) 
    pd={} 
    deck={"Red":0,"Red":1,"Red":2,"Red":3,"Red":4,"Red":5,"Red":6,"Red":7,"Red":8,"Red":9,"Blue":0,"Blue":1,"Blue":2,"Blue":3,"Blue":4,"Blue":5,"Blue":6,"Blue":7,"Blue":8,"Blue":9,"Green":0,"Green":1,"Green":2,"Green":3,"Green":4,"Green":5,"Green":6,"Green":7,"Green":8,"Green":9,"Yellow":0,"Yellow":1,"Yellow":2,"Yellow":3,"Yellow":4,"Yellow":5,"Yellow":6,"Yellow":7,"Yellow":8,"Yellow":9} 
    for i in range(1,nm): 
    c=random.choice(clist) 
    d=random.choice(nlist) 
    if ({c:d}) in deck: 
     pd.update({c:d}) 
     del deck[c:d] 
    else: 
     nm=nm+1 
    print("%s %s"%(c,d)) 
+3

与您的错误并不完全相关,但在创建它后立即尝试“打印(deck)”,您可能会惊讶地看到它有多少条目。 – Kevin

+0

呵呵,我看到最后一个条目是如何超越其他条目的;有没有办法来解决这个问题? –

+0

你为什么用随机来检查一个值是否在卡组里?似乎你应该循环所有组合。 – Julien

回答

1

随着if ({c:d}) in deck:,要检查如果字典{c:d}存在在词典中deck的关键。字典是不可干扰的(因为可变数据类型通常是),并且字典键必须是可散列的,所以不是只告诉你“不”,而是抛出你看到的错误。字典永远不会作为字典中的关键字出现。

此外,正如注释中所述,字典键是唯一的,所以您制作的字典不会像显示的那样存在。考虑不同的数据结构,如listtuple(例如[('Red', 1), ('Red', 2),...)或具有list值的字典(例如{'Red':[1, 2, 3,...], 'Blue':[1, 2, 3,...],...})。

0

您的具体错误来自您如何检查字典中的成员船。 in运算符检查给定键是否存在,但是您传递的是单元素字典而不仅仅是一个键(因为字典不是有效键,因为它们不能被散列),所以您会得到该特定的异常。

但是,正如凯文在上面评论的那样,您的deck字典不包含您想要包含的内容,因为您正在重复使用相同的密钥。字典只能有一个给定键的值(尽管该值可能是一个列表或元组,或者包含其他项的其他类型)。

有多种方法可以解决此问题。包含2元组的set将有点像你想要你的dict工作。您可以使用addremove元素,并有效地检查元组是否在集合中或与in运算符无关。然而,看着你在做什么,我认为对你的算法的更大改变将会好得多。而不是随机选择一种颜色和数字,然后检查它是否仍在deck中,您应该直接从集合中选择一个随机元素。而不是循环选择多个值,请使用random.sample一次选择所有值。或者,如果你打算在随后采取更多的随机数值,那么就分一杯羹。

下面是在2元组列表上使用random.shuffle的代码版本,然后从结尾切掉其中的10个,成为pd列表。

import itertools 
import random 

def CardGame(): 
    nm=8 
    clist = ["Red","Blue","Green","Yellow"] 
    nlist = list(range(0,10)) # this is easier than looping to append the values 
    deck = list(itertools.product(clist, nlist)) # much easier than naming them all 
    random.shuffle(deck) 
    pd = deck[-10:] # slice 10 items from the end 
    del deck[-10:] # and then remove them from the list (fairly efficient at the end)