[Python] heapq简介
[Python] heapq简介 « Lonely Coder
[Python] heapq简介
假设你需要维护一个列表,这个列表不断有新的元素加入,你需要在任何时候很方便的得到列表中的最大(小)值,因此要求列表始终处于排序完毕状态,。你会怎么做?
一个最简单的方法就是每次插入新的数据时,调用一次sort方法,这样可以保证列表的顺序。在数据量很小的情况下,这种方法可行,但如果数据量很大呢?要知道,Python中列表的sort方法实现并不高明,采用了一种不太有名的自然归并排序,虽然排序开销已经被尽量的压缩了,但仍然不是很理想,复杂度大概是O(nlogn)。
有没有更好的实现方法呢?答案是肯定的!在数据结构的世界里,只有想不到,没有做不到。
另一种解决方案就是heapq,它是Python的一个标准库。heapq实现了一种叫做堆的数据结构,是一种简洁的二叉树。他能确保父节点总是比子节点小,即满足
12#Python codelist[i] <=list[2*i+1]andlist[i] <=list[2*i+2]因此,list[0]就是最小的元素。在Python中维护一个堆最好的方式就是使用列表,并用库模块heapq来管理此列表。这个列表无需完成排序,但你却能够确保每次调用heappop从列表中获取元素时,总是当前最小的元素,然后所有节点会自动调整,以确保堆特性仍然有效。每次通过heappush添加元素或通过heappop删除元素时,开销大概是O(logn),在数据量很大时,明显要好于排序的方法。
下面,我将通过一个例子来说明适合堆使用的场景。
假设有一个很长的列表,并且周期性的有新的数据到达,你总是希望能够从队列中获取最重要的元素,而无需不断的重新排序或在整个队列中搜索。这个概念叫做优先级队列,而堆正是最适合实现他的数据结构。注意,heapq模块在每次调用heappop时向你提供最小的元素,因此需要安排你的元素的优先级值,以反应出元素的这个特点。举个例子,假设你每次收到一个数据都付一份钱,而任何时候最重要的元素都是队列中价格最高的那个;另外对于价格相同的元素,先到达的重要一些。下面的代码就是遵循这个要求,使用heapq实现的“优先级队列”类。
1234567891011classprioq(object):def__init__(self):self.q=[]self.i=0;defpush(self, item, cost):heapq.heappush(self.q, (-cost,self.i, item))self.i+=1defpop(self):returnheapq.heappop(self.q)代码中,将价格置为负数,作为原组的第一个元素,并将整个原组压入堆中,这样更高的出价便会产生更小的原组(基于Python的自然比较方式),在价钱之后,我们放置了一个递增索引,这样,当元素拥有相同的价钱时,先到达的元素将会处于更小的原组中。
需要说明的一点是,堆本身并不是一种有序的结构,但可以通过遍历二叉树的方式得到有序的列表。堆排序就是这么做的。
另外,Python在2.3中引入heapq模块,在2.4版本中又被重新实现和进一步优化了。更详细的使用说明,请参考Python标准库文档。
[Python] heapq简介的更多相关文章
- Python的简介以及安装和第一个程序以及用法
Python的简介: 1.Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.自从20世纪90年代初Python语言诞生至今,它逐渐被广泛应用于处理系统管理任务和Web编程.Pytho ...
- Python heapq 模块的实现 - A Geek's Page
Python heapq 模块的实现 - A Geek's Page Python heapq 模块的实现
- Python单元测试简介及Django中的单元测试
Python单元测试简介及Django中的单元测试 单元测试负责对最小的软件设计单元(模块)进行验证,unittest是Python自带的单元测试框架. 单元测试与功能测试都是日常开发中必不可少的部分 ...
- Python列表简介和遍历
一.Python3列表简介 1.1.Python列表简介 序列是Python中最基本的数据结构 序列中的每个值都有对应的位置值,称之为索引,第一个索引是0,第二个索引是1,以此类推. Python有6 ...
- python之最强王者(1)——python入门简介
1.Python简介 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年. 像Pe ...
- [python] 线程简介
参考:http://www.cnblogs.com/aylin/p/5601969.html 我是搬运工,特别感谢张岩林老师! python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件 ...
- python的简介及入门
前言 为何使用Python Python 是一种效率极高的语言.与其他众多的语言相比,实现相同功能,使用Python编写的程序包含的代码更少.Python的语法简单,易上手,使用Python编写的代码 ...
- Python Tornado简介
简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...
- 从一个集合中查找最大最小的N个元素——Python heapq 堆数据结构
Top N问题在搜索引擎.推荐系统领域应用很广, 如果用我们较为常见的语言,如C.C++.Java等,代码量至少也得五行,但是用Python的话,只用一个函数就能搞定,只需引入heapq(堆队列)这个 ...
随机推荐
- HTML5小游戏《智力大拼图》发布,挑战你的思维风暴
一,前言 本 游戏 是鄙人研究lufylegend数日之后,闲暇之余写下的.本游戏运用全新的技术 html 5写成的.游戏引擎为国产的lufylegend.js,大家可以去它的官网看看.游戏处于测 ...
- 新书:《Liferay Portal 6.1最佳实践门户网站建设》
新书:<Liferay Portal 6.1最佳实践门户网站建设> <Liferay Portal 6.1门户站点建设最佳实践>是国内第一本全面介绍Liferay Port ...
- 项目优化经验分享(六)SVN冲突和处理
上一篇博客我们分享了新增需求的确定思想<站在全局看问题>.今天我们来分享项目开发中SVN冲突的解决经验:SVN冲突和处理! 引言 开发过项目的人都知道,公司开发一个项目都会使用到版本号控制 ...
- iOS 编程之 使用 Xcode6配置.pch文件
刚上手 Xcode6 的人,总会发现之前在 6 之前常常会在“利用名-Prefix.pch”这个文件中来配置我们全局要用到的头文件,但是 xcode6 没有了,人家说,这类东西有时候也会出现1些稀里糊 ...
- NVelocity 实例
using System; using System.IO; using System.Collections; using System.Collections.Generic; using Sys ...
- 终于懂了:FWinControls子控件的显示是由Windows来管理,而不是由Delphi来管理(显示透明会导致计算无效区域的方式有所不同——透明的话应减少剪裁区域,所以要进行仔细计算)
在研究TCustomControl的显示过程中,怎么样都找不到刷新FWinControls并重新显示的代码: procedure TWinControl.PaintHandler(var Messag ...
- Cppcheck 1.54 C/C++静态代码分析工具
Cppcheck是一个C/C++代码分析工具,只检测那些编译器通常无法检测到的bug类型. 官方上建议让编译器提供尽量多的警告提示:1.使用Visual C++的话,应使用警告等级4 2.使用GC ...
- hdu1104 Remainder bfs找算式是否有解……
须要注意的是,进行模运算剪枝-- #include<iostream> #include<queue> #include<cstdlib> #include< ...
- php语言基础学习笔记
花了一个小时复习了一下很多年没有碰了的php,mark一下,高二时学的. 1. 代码嵌在<?php ?>内 2.输出函数echo,相当于js中的document.write 3.可以在打 ...
- css3 animation动画事件
当使用css3时,会遇到利用@keyframes来定义动画事件,利用以下3个事件,能够捕捉当前元素的动画: AnimationEnd //动画结束时 AnimationStart //动画開始 An ...