TypeError: '<' not supported between instances of 'State' and 'State' PYTHON 3

TypeError: '<' not supported between instances of 'State' and 'State' PYTHON 3

我正在尝试使用队列 class 中的 PriorityQueue。但是,我在将自定义对象放入我的 PQ 时遇到了问题。我已经实现了下面的 __cmp__ 功能:

def __cmp__(self, other):
    return (self.priority > other.priority) - (self.priority < other.priority)

我希望 PriorityQueue 按我的初始化函数中指定的优先级字段排序:

def __init__(self, board, priority=0):
    self.priority = priority
    # Other logic

但是,当我 运行 将 State 对象插入 PQ 的代码时,我收到此错误:TypeError: '<' not supported between instances of 'State' and 'State'

这是 运行PQ 的代码。

if op.precond(S):
            new_state = op.state_transf(S)
            if not (OPEN.queue.__contains__(new_state)) and not (new_state in CLOSED):
                GVALUES[Problem.hash(new_state)] = get_distance_value(op, new_state)
                HEUR_VALUES[Problem.hash(new_state)] = get_AStar_value(new_state)
                print("NEW STATE: " + str(new_state))
                OPEN.put(new_state)
                print("OPEN: " + str(OPEN.queue))

其中 OPEN 是 priorityQueue。

任何帮助将不胜感激...因为将值插入 PQ 应该非常简单。

在 Python 3 你需要定义 __lt____eq__ 而不是 __cmp__.

参见https://docs.python.org/3.1/library/stdtypes.html#comparisons

而不是 __cmp__ 您需要实现 __lt____le____gt____ge__ 方法之一并使用 functools.total_ordering装饰器

functools.total_ordering(cls) Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. This simplifies the effort involved in specifying all of the possible rich comparison operations:

The class must define one of __lt__(), __le__(), __gt__(), or __ge__(). In addition, the class should supply an __eq__() method.

然而,更好的解决方案是将元组 (priority, state_object) 放入队列,正如他们在 PriorityQueue

的文档中所建议的那样

The lowest valued entries are retrieved first (the lowest valued entry is the one returned by sorted(list(entries))[0]). A typical pattern for entries is a tuple in the form: (priority_number, data).

第一种方法的缺陷在于您可以修改已在队列中的项目的优先级并可能观察到意外行为。

在第二种方法中,这不是问题,因为元组是不可变的。

扩展Sean Fujiwara所说的,你需要定义两个函数如下:

class Widget():
  def __gt__(self, other):
    return self.title > other.title

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

  def __init__(self, title):
    self.title = value

在此示例中,添加 __gt__ __lt__ 方法让我们可以按小部件的标题排序。