《Python Cookbook(第3版)中文版》——1.5 实现优先级队列
本节书摘来自异步社区《Python Cookbook(第3版)中文版》一书中的第1章,第1.5节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.5 实现优先级队列
1.5.1 问题
我们想要实现一个队列,它能够以给定的优先级来对元素排序,且每次pop操作时都会返回优先级最高的那个元素。
1.5.2 解决方案
下面的类利用heapq模块实现了一个简单的优先级队列:
import heapq
class PriorityQueue:def __init__(self):self._queue = []self._index = 0def push(self, item, priority):heapq.heappush(self._queue, (-priority, self._index, item))self._index += 1def pop(self):return heapq.heappop(self._queue)[-1]
下面是如何使用这个类的例子:
>>> class 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)
>>> q.pop()
Item('bar')
>>> q.pop()
Item('spam')
>>> q.pop()
Item('foo')
>>> q.pop()
Item('grok')
>>>
请注意观察,第一次执行pop()操作时返回的元素具有最高的优先级。我们也观察到拥有相同优先级的两个元素(foo和grok)返回的顺序同它们插入到队列时的顺序相同。
1.5.3 讨论
上面的代码片段的核心在于heapq模块的使用。函数heapq.heappush()以及heapq.heappop()分别实现将元素从列表_queue中插入和移除,且保证列表中第一个元素的优先级最低(如1.4节所述)。heappop()方法总是返回“最小”的元素,因此这就是让队列能弹出正确元素的关键。此外,由于push和pop操作的复杂度都是O(logN),其中N代表堆中元素的数量,因此就算N的值很大,这些操作的效率也非常高。
在这段代码中,队列以元组(-priority, index, item)的形式组成。把priority取负值是为了让队列能够按元素的优先级从高到低的顺序排列。这和正常的堆排列顺序相反,一般情况下堆是按从小到大的顺序排序的。
变量index的作用是为了将具有相同优先级的元素以适当的顺序排列。通过维护一个不断递增的索引,元素将以它们入队列时的顺序来排列。但是,index在对具有相同优先级的元素间做比较操作时同样扮演了重要的角色。
为了说明Item实例是没法进行次序比较的,我们来看下面这个例子:
>>> a = Item('foo')
>>> b = Item('bar')
>>> a < b
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: unorderable types: Item() < Item()
>>>
如果以元组(priority, item)的形式来表示元素,那么只要优先级不同,它们就可以进行比较。但是,如果两个元组的优先级值相同,做比较操作时还是会像之前那样失败。例如:
>>> a = (1, Item('foo'))
>>> b = (5, Item('bar'))
>>> a < b
True
>>> c = (1, Item('grok'))
>>> a < c
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: unorderable types: Item() < Item()
>>>
通过引入额外的索引值,以(prioroty, index, item)的方式建立元组,就可以完全避免这个问题。因为没有哪两个元组会有相同的index值(一旦比较操作的结果可以确定,Python就不会再去比较剩下的元组元素了):
>>> a = (1, 0, Item('foo'))
>>> b = (5, 1, Item('bar'))
>>> c = (1, 2, Item('grok'))
>>> a < b
True
>>> a < c
True
>>>
如果想将这个队列用于线程间通信,还需要增加适当的锁和信号机制。请参见12.3节的示例学习如何去做。
关于堆的理论和实现在heapq模块的文档中有着详细的示例和相关讨论。
《Python Cookbook(第3版)中文版》——1.5 实现优先级队列相关推荐
- python cookbook pdf下载-Python Cookbook 第3版 中文版.pdf
作 者 :(美)比斯利,(美)琼斯著 出版发行 : 北京:人民邮电出版社 , 2015.05 ISBN号 :978-7-115-37959-7 页 数 : 684 原书定价 : 108.00 开本 : ...
- Python Cookbook(第3版)中文版:15.17 传递文件名给C扩展
15.17 传递文件名给C扩展¶ 问题¶ 你需要向C库函数传递文件名,但是需要确保文件名根据系统期望的文件名编码方式编码过. 解决方案¶ 写一个接受一个文件名为参数的扩展函数,如下这样: static ...
- Python Cookbook(第3版)中文版:15.18 传递已打开的文件给C扩展
15.18 传递已打开的文件给C扩展¶ 问题¶ 你在Python中有一个打开的文件对象,但是需要将它传给要使用这个文件的C扩展. 解决方案¶ 要将一个文件转换为一个整型的文件描述符,使用 PyFile ...
- python书籍推荐:Python Cookbook第三版中文
所属网站分类: 资源下载 > python电子书 作者:熊猫烧香 链接:http://www.pythonheidong.com/blog/article/44/ 来源:python黑洞网 内容 ...
- python序列中各元素之间存在顺序关系_《Python Cookbook(第3版)中文版》——1.10 从序列中移除重复项且保持元素间顺序不变-阿里云开发者社区...
本节书摘来自异步社区<Python Cookbook(第3版)中文版>一书中的第1章,第1.10节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节 ...
- 《Python Cookbook(第3版)中文版》——1.9 在两个字典中寻找相同点
本节书摘来自异步社区<Python Cookbook(第3版)中文版>一书中的第1章,第1.9节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节内 ...
- 不属于python标准库的是_《Python Cookbook(第2版)中文版》——1.10 过滤字符串中不属于指定集合的字符-阿里云开发者社区...
本节书摘来自异步社区<Python Cookbook(第2版)中文版>一书中的第1章,第1.10节,作者[美]Alex Martelli , Anna Martelli Ravenscro ...
- 【好书分享】《Python Cookbook》第三版 中文版(带书签)
[书籍介绍] 带完整书签 书籍中的文字可复制 [获取方式] <Python Cookbook>第三版 中文版.rar: https://url00.ctfile.com/f/1936360 ...
- python cookbook 中文版 第 3 版-《Python Cookbook》第三版中文版
人生苦短,我用 python! 我一直坚持使用 python3,因为它代表了python的未来.虽然向后兼容是它的硬伤,但是这个局面迟早会改变的, 而且python3的未来需要每个人的帮助和支持. 目 ...
最新文章
- STM32学习笔记9(SysTick滴答时钟)
- RHEL5 install
- 用python画图代码简单-【Matplotlib】利用Python进行绘图
- 【AI产品】超长文详解作业帮产品逻辑和技术原理
- shiro+springboot分析思路
- IntelliTrace 调试、定位异常
- `if __name__ == __main__`模块运行代码管理
- linux 关闭redis 命令_面试必问的 Redis:RDB、AOF、混合持久化
- Q91:真实地模拟透明材质(Realistic Transparency)(2)——Triangle Meshes
- RPC框架dubbo架构原理及使用说明
- 易语言使用超级模块 全局热键
- css 入场动画_进入css3动画世界(一)
- 知道君推荐给大家一些写论文、搞科研、读大学必备的30款软件。
- 苹果手机小圆点怎么设置?悬浮球设置,轻松学会
- Mac 超详细入门指南,备用!
- 题都城南庄---中华诗词-唐五代-崔护
- 制作ipad iphone充电线
- 什么是Nofollow
- 异或、异或和 的性质及应用总结
- 笔记 shell基础应用,texturePacker 命令批量打包打包
热门文章
- linux 路由访问不了php文件,linux系统nginx服务器不能访问php文件问题
- python 怎么样才有output_[学]Python用户手册笔记_4_Input and Output
- oracle24550,ORA-24550: signal received:这个问题的原因及解决办法
- oracle向右削减和补全,b操纵序列削减Oracle数据库开辟工作量-开辟技术/b[Oracle防范]...
- python中xlrd写操作_Python读写操作Excel模块_xlrd_xlwt_xlutils
- Vue3 插槽使用详解
- 工作占用了太多私人时间_一本正经聊驾驶 | 汽车真的为我们节约时间了吗
- 2020年9月北京计算机等级考试考点,2020年9月北京计算机等级考试考点设置
- python自动化测试学习有用吗_python自动化测试学习-UnitTest/PyUnit的用法介绍
- Android的Animator动画(平移,渐隐,旋转,缩放)