从字典中迭代值时遇到类型错误

时间:2018-11-16 14:04:20

标签: python python-3.x

我正在尝试创建一个程序,用于为骰子的每一卷返回棋盘上的位置(从位置0开始)。

我的词典中包含键,它们是板上的位置 和值,即

应该发生的位移。

dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43, 
              95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}

例如,当我降落到位置64时,我在字典中找到了键64,然后从64移到板上的-4,紧靠60。

我下面有我的当前代码。

def location(rolls):
dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43, 
              95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}

    position = 0
    list_position = []
    for roll in rolls:
        position = position + roll

        if position not in dictionary:
            pass
        if position in dictionary:
            position = position + dictionary.get(roll)
            list_position.append(position)
        print(position)

我正在获得部分职位,我相信一些迭代会返回类型错误。

>>> location([1, 4, 5])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 12, in location
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
38
42

# desired output
[38, 42, 26]

从骰子的第一卷开始,我们降落到位置1。我们在字典中找到1,并得知我

必须移动37,然后停在38上。从骰子的第二卷开始,我们从38移动4并着陆

在42上。42不在我的词典中,因此我们放在42上。然后从骰子的第三卷开始,移动5

从42开始,到达47。47在我的字典中,而我从47移到-21,到达26。

所以我实际上在列表中排在前两位。我没有一个线索,为什么第三个

位置未打印,并返回此类型错误。

3 个答案:

答案 0 :(得分:2)

您的代码存在一些结构性问题:

  1. 检查应该是一个大的if块,而不是2个单独的块:

    if position not in dictionary:
        pass
    else:   # <-- use else instead
        position = position + dictionary.get(roll)
        list_position.append(position)
    print(position)
    

由于这两个条件是相反的,所以没有必要再进行position in dictionary检查。

更好-由于position not in dictionary甚至不需要执行任何操作,因此只需执行以下操作:

if position in dictionary:
    position = position + dictionary.get(roll)
    list_position.append(position)
# you don't need an else because you don't intend to do anything
  1. dictionary.get(roll)不受条件控制。您将检查是否position in dictionary,但不能确保roll也位于dictionary中。因此,当dict.get()不在其中时,默认情况下会返回None

您可以设置诸如dictionary.get(roll, 0)之类的默认值,也可以将您想定义的所有可能的卷填充到词典中,或者检查roll in dictionary

答案 1 :(得分:1)

问题是position = position + dictionary.get(roll)。在滚动为5的第三次迭代中,dictionary.get(roll)的计算结果为无。

编辑:另外,如果您想跳到for循环的下一个迭代,则正确的语法是继续,而不是通过。

我在下面添加了一张支票:

def location(rolls):
    dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43,
                  95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}
    position = 0
    list_position = []
    for roll in rolls:
        position = position + roll
        if position not in dictionary:
            continue # pass does nothing here
        if position in dictionary:
            if dictionary.get(roll):
                position = position + dictionary.get(roll)
            list_position.append(position)
        print(position)

location([1, 4, 5])

答案 2 :(得分:1)

  1. 我认为list_positionposition_list应该是相同的列表
  2. 5不在字典中(因为您没有检查roll,因此只检查了position),因此它返回None,您肯定无法将None添加到整数。为不存在的密钥添加默认值。
  3. 一个小建议;您在此处使用的if的{​​{1}}情况几乎没有任何作用。您可能只检查密钥是否在字典中。

编辑:看来OP的意思是pass。在这种情况下,我们无需检查任何内容。

这是我的意思:

dictionary.get(position)

运行它:

def location(rolls):
  dictionary = {64: -4, 49: -38, 98: -20, 16: -10, 87: -63, 56: -3, 47: -21, 93: -20, 62: -43, 
              95: -20, 80: 20, 1: 37, 51: 16, 4: 10, 21: 21, 71: 20, 9: 22, 28: 56, 36: 8}

  position = 0
  list_position = []
  for roll in rolls:
    position = position + roll
    # if position not in dictionary:  # commented out
    #     pass                        # 
    # if position in dictionary:      # no need to check anything since default is 0
    position = position + dictionary.get(position, 0)
    list_position.append(position)    # fixed the name
    print(position)

输出:

location([1, 4, 5])