用户定义的类型作为字典键

时间:2014-04-23 20:55:05

标签: python dictionary

过去几天我一直在努力使用哈希表和词典的概念,而且无法找到解决问题的正确方法。我希望你能原谅我的初学者(可能是重复的)问题,并且有时间回答我。

在我的" World" (FSM是解决经典GridWorld MDP问题的一部分,但这不是问题)我已经创建了State的各种实例,每个实例都有一个独特且具有特征的元组(row, column)。我的问题是如何存储和引用这些实例。

更具体......

我使用以下代码创建了几个状态(在使用其他几个替代方法失败后使用列表存储它们,例如字典,集和NumPy数组):

(rows, columns) = (3, 4)
s = [[] for _ in range(rows)]
for r in range(rows):
    for c in range(columns):
        s[r].append(State(r, c))

其中类由:

定义
class State:
    def __init__(self, row, col):
        self.row = row
        self.col = col

    def __hash__(self):
        return hash((self.row, self.col))

    def __eq__(self, other):
        return (self.row == other.row) & (self.col == other.col)

    # __hash__ and __eq__ are here because I know they should,
    # though I currently don't know how to use them.
    # I believe that is actually the real question here...

稍后在我的代码中,我希望为每个州分配一个属性neighbours,该属性是网格上靠近它的实际状态的列表。通过"实际"我的意思是他们不是州的副本或州的一些代表,而是州自己。下面你可以找到我不知道我在寻找的实现:

def add_neighbours(self):
    if self.row == 0:
        if self.col == 0:
            self.neighbours = [(0, 1), (1, 0)]
        elif self.col == 1:
            self.neighbours = [(0, 0), (0, 2)]
        elif self.col == 2:
            self.neighbours = [(0, 1), (1, 2), (0, 3)]
        elif self.col == 3:
            self.neighbours = [(0, 2), (1, 3)]
    elif self.row == 1:
        if self.col == 0:
            self.neighbours = [(0, 0), (2, 0)]
        elif self.col == 1:
            self.neighbours = []  # Pit, N/A
        elif self.col == 2:
            self.neighbours = [(0, 2), (1, 3), (2, 2)]
        elif self.col == 3:
            self.neighbours = [(0, 3), (1, 2), (2, 3)]
    elif self.row == 2:
        if self.col == 0:
            self.neighbours = [(1, 0), (2, 1)]
        elif self.col == 1:
            self.neighbours = [(2, 0), (2, 2)]
        elif self.col == 2:
            self.neighbours = [(2, 1), (1, 2), (2, 3)]
        elif self.col == 3:
            self.neighbours = [(2, 2), (1, 3)]

neighbours的这个定义允许我从s调用相关的状态,但这不是一个美丽的景象而且不是优雅的。我寻找的东西是那种:

def add_neighbours(self):
    if self.row == 0:
        if self.col == 0:
            self.neighbours = [State((0, 1)), State((1, 0))]
        elif self.col == 1:
            self.neighbours = [State((0, 0)), State((0, 2))]
        elif self.col == 2:
            self.neighbours = [State((0, 1)), State((1, 2)), State((0, 3))]
etc...

其中State((r, c))实际状态(或者我应该说是对状态的引用),一次又一次地调用。

任何评论都将不胜感激。感谢。

注意:我知道详细的解释尝试(例如this Stack Overflow questionthis Python Wiki reference,但遗憾的是我没有解决这些问题,不得不要求更多解释。

1 个答案:

答案 0 :(得分:0)

这是一个平面图,每个节点都可以用矩阵定位和索引。

你能做的是:

  1. 创建支持索引结构以存储每个单独的单元格,以便您可以通过其坐标引用单元格。
  2. 创建每个空的单个单元格并存储在支持索引结构中。
  3. 创建每个空单元格后,将每个单元格链接到其邻居。
  4. 您需要先将每个状态创建为空,因为您无法引用尚未创建的对象。

    在代码中:

    # 1. Backing index
    table = {}
    
    # 2. Each State is empty.
    table[(0, 0)] = State(0, 0)
    table[(0, 1)] = State(0, 1)
    table[(1, 0)] = State(1, 0)
    table[(1, 1)] = State(1, 1)
    # ...
    
    # 3. Initialize each State.
    table[(0, 0)].initialize()
    table[(0, 1)].initialize()
    # ...
    
    class State:
      def initialize(self):
        if ...:
          # self.neighbours is a list of States.
          self.neighbours = [table[(x, y)], table[(a, b)], table[(p, q)]]
    
相关问题