首页 > 编程 > Python > 正文

Python cookbook(数据结构与算法)实现优先级队列的方法示例

2020-01-04 15:50:46
字体:
来源:转载
供稿:网友

本文实例讲述了Python实现优先级队列的方法。分享给大家供大家参考,具体如下:

问题:要实现一个队列,它能够以给定的优先级对元素排序,且每次pop操作时都会返回优先级最高的那个元素;

解决方案:采用heapq模块实现一个简单的优先级队列

# example.py## Example of a priority queueimport heapqclass PriorityQueue:  def __init__(self):    self._queue = []    self._index = 0  def push(self, item, priority):    heapq.heappush(self._queue, (-priority, self._index, item))    self._index += 1  def pop(self):    return heapq.heappop(self._queue)[-1]# Example useclass Item:  def __init__(self, name):    self.name = name  def __repr__(self):    return 'Item({!r})'.format(self.name)q = PriorityQueue()q.push(Item('foo'), 1)q.push(Item('bar'), 5)q.push(Item('spam'), 4)q.push(Item('grok'), 1)print("Should be bar:", q.pop())print("Should be spam:", q.pop())print("Should be foo:", q.pop())print("Should be grok:", q.pop())
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:24:06) [MSC v.1600 32 bit (Intel)] on win32Type "copyright", "credits" or "license()" for more information.>>> ================================ RESTART ================================>>> Should be bar: Item('bar')Should be spam: Item('spam')Should be foo: Item('foo')Should be grok: Item('grok')>>> 

可以看出:第一次执行pop()操作时返回的元素具有最高的优先级;对于相同优先级的两个元素(foo和gork)返回的顺序同它们插入到队列时的顺序相同。

在这段代码中,队列以元组(-priority, self._index, item)的形式组成,priority取负值是为了队列按照从高到低的顺序排列,这和堆默认的从小到大的排序相反。

变量index的作用是对相同优先级的元素以适当的顺序排列,特别对同优先级的元素间做比较操作时扮演了重要的角色。

Item实例无法进行次序比较:

a=Item('foo')b=Item('bar')print('a<b: ',a<b)>>> Traceback (most recent call last): File "D:/4autotests/02script/python-cookbook/python-cookbook-master/src/1/5.implementing_a_priority_queue/example.py", line 27, in <module>  print('a<b: ',a<b)TypeError: unorderable types: Item() < Item()>>> 

如果以元组(priority,  item)的形式来表示元素,只要优先级不同,就可进行比较:

a=(1,Item('foo'))b=(5,Item('bar'))c=(1,Item('gork'))print('a<b: ',a<b)print('a<c: ',a<c)>>> a<b: TrueTraceback (most recent call last): File "D:/4autotests/02script/python-cookbook/python-cookbook-master/src/1/5.implementing_a_priority_queue/example.py", line 29, in <module>  print('a<c: ',a<c)TypeError: unorderable types: Item() < Item()>>> 

引入额外的索引值,以(priority, index, item)的方式建立元组,就可以避免相同优先级无法比较的问题,因为没有哪两个元组会有相同的index值;

a=(1,0,Item('foo'))b=(5,1,Item('bar'))c=(1,2,Item('gork'))print('a<b: ',a<b)print('a<c: ',a<c)>>> a<b: Truea<c: True>>>

如果想将这个队列用于线程间通信,还需要增加适当的锁和信号机制。

希望本文所述对大家Python程序设计有所帮助。


注:相关教程知识阅读请移步到python教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表