6

我从客户端接收服务器对象(每个对象都具有相同的结构并具有包含该对象创建时间的字段 self.utc_time)。我需要存储在某种结构中,所以我总是按升序排序,所以当我弹出时,我会按 utc_time 弹出最旧的对象,而不是按我收到的时间。我想使用 heapq 中的优先级队列,但是如何说通过自定义对象中的 utc_time 字段进行 heaify 呢?有更好的解决方案吗?

4

2 回答 2

27

魔术__cmp__比较方法添加到您的类中,以避免需要执行 Maksim 描述的元组装饰:

>>> import heapq
>>> class MyObject(object):
...     def __init__(self, val):
...         self.val = val
...     def __cmp__(self, other):
...         return cmp(self.val, other.val)
...         
...     
... 
>>> q = []
>>> heapq.heappush(q, MyObject(50))
>>> heapq.heappush(q, MyObject(40))
>>> heapq.heappush(q, MyObject(30))
>>> heapq.heappush(q, MyObject(20))
>>> heapq.heappush(q, MyObject(200))
>>> obj = heapq.heappop(q)
>>> print obj.val
20

注意:__lt__Python 3中覆盖,__cmp__仅在 Python 2 中

于 2012-08-16T14:46:07.187 回答
9

Python 文档隐含地提供了以下解决方案:

堆元素可以是元组。这对于在跟踪的主记录旁边分配比较值(例如任务优先级)很有用:

 h = []
 heappush(h, (5, 'write code'))
 heappush(h, (7, 'release product'))
 heappush(h, (1, 'write spec'))
 heappush(h, (3, 'create tests'))
 heappop(h)
   => (1, 'write spec')

您可以以类似的方式执行此操作 - 存储元组,其中第一个元素将包含utc_time放置到 PQ 的对象的 a 和第二个元素 - 对对象本身的引用。

在类似的SO question中,建议创建一个易于使用的包装器,该包装器将允许以更简洁的方式使用优先级队列。

于 2012-08-16T14:31:21.883 回答