我注意到无法对对象使用PriorityQueue?

6 投票
1 回答
14815 浏览
提问于 2025-04-17 13:04

我有一个叫做ADT(进程控制块,简称PCB)的东西,我想把它们放进一个优先队列里。请问我该怎么做?

我已经参考了如何将项目放入优先队列?,用来设置一个次要优先级,以确保队列的正确顺序。在这里,我可以让PCB可以进行比较,但在另一个类里,这样做可能就不太合适了?那我该怎么办呢?

更新

我的代码和https://stackoverflow.com/a/9289760/292291上发布的非常相似。

class PCB:
    ...

# in my class extending `PriorityQueue`
PriorityQueue.put(self, (priority, self.counter, pcb))

我觉得问题在于pcb在这里还是不能进行比较。

1 个回答

12

好的,来总结一下这个问题。我做了以下几件事:

让这个抽象数据类型(ADT)可以比较:实现了 __lt__() 方法。

def __lt__(self, other):
    selfPriority = (self.priority, self.pid)
    otherPriority = (other.priority, other.pid)
    return selfPriority < otherPriority

这样,我就可以简单地使用 queue.put(obj) 来放入对象了。

我发现 @larsmans 说得对:

如果优先级和计数器总是可以比较,并且没有两个计数器的值是相同的,那么整个三元组都是可以比较的

jiewmeng@JM:~$ python3.2
Python 3.2.2 (default, Sep  5 2011, 21:17:14) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Test:
...     def __init__(self, name):
...             self.name = name
... 
>>> from queue import PriorityQueue
>>> q = PriorityQueue()

# duplicate priorities triggering unorderable error
>>> q.put((2, Test("test1")))
>>> q.put((1, Test("test1")))
>>> q.put((3, Test("test1")))
>>> q.put((3, Test("test1")))
>>> q.put((3, Test("test2")))
>>> while not q.empty():
...     print(q.get().name)
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python3.2/queue.py", line 195, in get
    item = self._get()
  File "/usr/lib/python3.2/queue.py", line 245, in _get
    return heappop(self.queue)
TypeError: unorderable types: Test() < Test()

# unique priority fields thus avoiding the problem
>>> q = PriorityQueue()
>>> q.put((3, Test("test1")))
>>> q.put((5, Test("test5")))

>>> while not q.empty():
...     print(q.get()[1].name)
... 
test1
test5

撰写回答