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

Python 作为字典键的用户定义类型,python,dictionary,Python,Dictionary,在过去的几天里,我一直在与哈希表和字典的概念作斗争,却找不到解决问题的正确方法。我希望您能原谅我的初学者和可能重复的问题,并抽出时间回答我 在我的World FSM初始化期间,作为解决经典GridWorld MDP问题的一部分,但这不是这里的问题,我创建了各种状态实例,每个实例都有一个唯一且具有特征的元组行、列。我的问题是如何存储和引用这些实例 更具体地说。。。 我使用以下代码创建了几个状态,在其他几个选项(例如字典、集合和NumPy数组)失败后,使用列表存储这些状态: (rows, colum

在过去的几天里,我一直在与哈希表和字典的概念作斗争,却找不到解决问题的正确方法。我希望您能原谅我的初学者和可能重复的问题,并抽出时间回答我

在我的World FSM初始化期间,作为解决经典GridWorld MDP问题的一部分,但这不是这里的问题,我创建了各种状态实例,每个实例都有一个唯一且具有特征的元组行、列。我的问题是如何存储和引用这些实例

更具体地说。。。 我使用以下代码创建了几个状态,在其他几个选项(例如字典、集合和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...
在我的代码后面,我希望为每个状态分配一个属性neights,它是网格上靠近它的实际状态的列表。我的实际意思是,它们不是国家的复制品或国家的某种代表,而是国家本身。在下面,您可以找到我的非我所期待的实施:

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)]
邻居的这个定义让我可以从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...
其中Stater,c是实际状态,或者我应该说是对反复调用的状态的引用

如有任何意见,将不胜感激。谢谢


注:我知道有详细的解释尝试,例如和,但不幸的是,我没有解决这些问题,不得不要求更多的解释。

这是一个平面图,每个节点都可以通过矩阵进行定位和索引

您可以做的是:

创建一个备份索引结构来存储每个单元格,这样您就可以通过单元格的坐标来引用单元格。 创建每个空的单个单元格并存储在备份索引结构中。 创建每个空单元后,将每个单元链接到其相邻单元。 您需要首先将每个状态创建为空,因为您不能引用尚未创建的对象

代码:

# 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)]]

最初我认为我应该使用它,但我不知道如何使用,所以经过几次尝试后,我已经放弃了它。这就是我问这个问题的基本原因…这个问题不清楚。什么是MDP?国家意味着什么?你想干什么?您正在翻译其他编程语言的代码吗?你知道其他编程语言吗?这听起来像是一张图表,但我不确定。我尽量弄清楚。MDP的背景在这里是不相关的,在这个上下文中,状态是网格上的一个位置。如果方便的话,你可能会想到学生而不是州,坐在一个3x4大小的班级里。问题将保持不变。因此,你有一个矩阵,并为每个单元格显式列出每个邻居。对,对。我希望这份名单能包含真正的邻居。谢谢!这是有效的。然而,我仍然对“hash”和“eq”的必要性感到好奇,我真的希望看到它们在工作中的一个好例子。顺便说一句-我不能投票支持你,因为它至少需要15个声誉…@user3121900你只需要使一个对象可散列,因为你正在使用该对象作为密钥。就是这样,你已经有了这个对象的一个实例,你想要得到一些其他的信息。事实并非如此,因为您要获取其实例的对象是State对象。这里我们使用一个简单的坐标元组来获取State实例。