当对现有密钥执行dict [k]:KeyError时,dict.keys()返回的密钥k会导致KeyError

时间:2017-09-26 04:59:13

标签: python python-3.x dictionary keyerror

以下代码

for k in list(g_score.keys()):
    print(g_score[k])

为我返回KeyError

Traceback (most recent call last):
  File "./np.py", line 134, in <module>
    main()
  File "./np.py", line 131, in main
    NPuzzle(n).solve()
  File "./np.py", line 116, in solve
    print(g_score[k])
KeyError: 3

print(list(g_score.keys())) [4, 3, 7]时,我不明白这是怎么回事。 3明显属于词典。

对于上下文,我试图实现A *搜索N-Puzzle问题(我甚至不确定A *是否正确实现,因为我无法通过此错误),并具有以下State类和solve函数:

class State:
    def __init__(self, blank_idx, puzzle, g=0, h=0):
        self.blank_idx = blank_idx
        self.puzzle = puzzle
        self.f = g + h

    def __eq__(self, other):
        return self.puzzle == other.puzzle

    def __hash__(self):
        return self.f + self.blank_idx

    def __lt__(self, other):
        return self.f < other.f

    def __repr__(self):
        return str(self.f)

...

class NPuzzle:

    # ...other stuff

    def solve(self):
      start_state = State(
          self.puzzle.index(' '),
          self.puzzle,
          0,
          self.cost(self.puzzle)
      )

      g_score = {start_state: 0}
      open_set = [start_state]
      path = {}

      while open_set:
          state = open_set[0]

          if state.puzzle == self.goal_state:
              break

          heappop(open_set)
          for next_state in self.neighbors(state):
              g = g_score[state] + 1
              if next_state in g_score and g >= g_score[next_state]:
                  continue

              path[next_state] = state
              g_score[next_state] = g
              next_state.f = g + self.cost(next_state.puzzle)
              heappush(open_set, next_state)

我第一次在我所在的行上遇到错误:

g = g_score[state] + 1

我不确定为什么会出现KeyError,但我想假设它可能与我的自定义__hash()__功能有关。

1 个答案:

答案 0 :(得分:1)

好的事实证明问题是我立即改变了哈希函数所依赖的State实例的属性... oops:

__hash()__的{​​{1}}功能是:

State

以及我在return self.f + self.blank_idx 中存储State的方式如下:

g_score

由于它使用g_score[next_state] = g next_state.f = g + self.cost(next_state.puzzle) next_state.f放入next_state,但是在下一行我立即变异g_score

切换两个语句的顺序如下:

next_state.f

解决了我的问题。