不可用类型“Dict”

时间:2015-11-03 02:09:06

标签: python

我正在编写一个基本的uno-type纸牌游戏,并希望能够(同时为玩家制作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))

2 个答案:

答案 0 :(得分:1)

使用if ({c:d}) in deck:,您正在检查词典{c:d}是否作为词典deck中的键存在。字典是不可删除的(通常是可变数据类型),字典键必须是可清除的,所以它不会只是告诉你“不”,而是抛出你看到的错误。字典永远不会作为字典中的键出现。

此外,如评论中所述,字典键是唯一的,因此您创建的字典不会显示。考虑使用不同的数据结构,例如list tuple s(例如[('Red', 1), ('Red', 2),...)或带有list值的字典(例如{'Red':[1, 2, 3,...], 'Blue':[1, 2, 3,...],...})。

答案 1 :(得分:0)

您的具体错误来自于您在字典中检查成员发货的方式。 in运算符检查是否存在给定键,但是您传递的是单元素字典而不仅仅是一个键(由于字典不是有效键,因此字典不是有效键,因此会得到该特定异常)。

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

您可以通过多种方式解决此问题。包含2元组的set有点像您希望dict工作的方式。您可以使用addremove元素,并使用in运算符有效地检查元组是否在集合中。

但是,看看你实际在做什么,我认为你的算法会有更大的改变。您应该直接从集合中选择一个随机元素,而不是随机选择颜色和数字,然后检查它是否仍在deck中。不要循环选择多个值,而是使用random.sample一次选择所有值。或者,如果您稍后要从套牌中获取更多随机值,shuffle它并采取切片。

这是在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)