[Python] heapq简介 « Lonely Coder
[Python] heapq简介
假设你需要维护一个列表,这个列表不断有新的元素加入,你需要在任何时候很方便的得到列表中的最大(小)值,因此要求列表始终处于排序完毕状态,。你会怎么做?
一个最简单的方法就是每次插入新的数据时,调用一次sort方法,这样可以保证列表的顺序。在数据量很小的情况下,这种方法可行,但如果数据量很大呢?要知道,Python中列表的sort方法实现并不高明,采用了一种不太有名的自然归并排序,虽然排序开销已经被尽量的压缩了,但仍然不是很理想,复杂度大概是O(nlogn)。
有没有更好的实现方法呢?答案是肯定的!在数据结构的世界里,只有想不到,没有做不到。
另一种解决方案就是heapq,它是Python的一个标准库。heapq实现了一种叫做堆的数据结构,是一种简洁的二叉树。他能确保父节点总是比子节点小,即满足
12#Python code
list
[i] <
=
list
[
2
*
i
+
1
]
and
list
[i] <
=
list
[
2
*
i
+
2
]
因此,list[0]就是最小的元素。在Python中维护一个堆最好的方式就是使用列表,并用库模块heapq来管理此列表。这个列表无需完成排序,但你却能够确保每次调用heappop从列表中获取元素时,总是当前最小的元素,然后所有节点会自动调整,以确保堆特性仍然有效。每次通过heappush添加元素或通过heappop删除元素时,开销大概是O(logn),在数据量很大时,明显要好于排序的方法。
下面,我将通过一个例子来说明适合堆使用的场景。
假设有一个很长的列表,并且周期性的有新的数据到达,你总是希望能够从队列中获取最重要的元素,而无需不断的重新排序或在整个队列中搜索。这个概念叫做优先级队列,而堆正是最适合实现他的数据结构。注意,heapq模块在每次调用heappop时向你提供最小的元素,因此需要安排你的元素的优先级值,以反应出元素的这个特点。举个例子,假设你每次收到一个数据都付一份钱,而任何时候最重要的元素都是队列中价格最高的那个;另外对于价格相同的元素,先到达的重要一些。下面的代码就是遵循这个要求,使用heapq实现的“优先级队列”类。
1234567891011class
prioq(
object
):
def
__init__(
self
):
self
.q
=
[]
self
.i
=
0
;
def
push(
self
, item, cost):
heapq.heappush(
self
.q, (
-
cost,
self
.i, item))
self
.i
+
=
1
def
pop(
self
):
return
heapq.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(堆队列)这个 ...
随机推荐
-
IE 8 下的 box-sizing 和 min-* 属性
在非 IE 浏览器中,默认情况下 width 属性指的是内容区域(content)的宽度. IE 6+ 中,如果浏览器以标准模型渲染,和非 IE 浏览器的表现是一致的:如果浏览器以怪癖模式渲染,则 w ...
-
textview 显示html方法解析
现在网络的繁盛时代,光文字是不能满足人们的胃口的,图片,flash,音频,视频就成为浏览网页的主流显示,在手机上也一样.在手机上显示从网络端获取的数据显示,大家很自然的想起两种方式,一种就是webvi ...
-
contains
ArrayLIst类使用contains方法时要注意:放入ArrayList中的类必须要重写equals方法(既然equals重写了,那么 hash方法也应该重写,这两个方法一般同时重写):如果不重写 ...
-
android 开发 制作弹出等待进度条
技术点: dialog:ProgressBar:animated-rotate: 弹出框: import com.carspeak.client.R; import android.app.Dialo ...
- SSM成功了
-
HTML5 Canvas核心技术—图形、动画与游戏开发.pdf7
性能 运行putImageData()比drawImage()慢,同等条件下优先考虑drawImage() 操作图像数据需要遍历大量数据,应该注意几点: 1)避免在循环体中直接访问对象属性,应当保存在 ...
-
模板类之间的友元关系实现Blob和BlobPtr
16.12编写你自己版本的Blob和BlobPtr模板,包含书中未定义的多个const成员. Blob.h(注意,成员函数的声明和定义要放在一个头文件中) /*记住,模板的头文件中通常既包括声明也包括 ...
-
Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar
ok,今天继续更新Material Design系列!!! 废话不说,先看看效果图吧: 好了,现在来讲讲上图是怎么实现的吧!讲之前先讲讲几个控件: CoordinatorLayout 该控件也是De ...
-
轻量化卷积神经网络MobileNet论文详解(V1&;V2)
本文是 Google 团队在 MobileNet 基础上提出的 MobileNetV2,其同样是一个轻量化卷积神经网络.目标主要是在提升现有算法的精度的同时也提升速度,以便加速深度网络在移动端的应用.
-
从原型链探究Javascript这么火的原因
首先,此文是对于javascript原型链的一些私人见解,若能博君会心一笑,在下荣幸之至! 为了阐述我的理解,首先提前声明一些前置知识,欢迎指正: 栈内存和堆内存: 栈内存每个地址分配的地址长度较窄, ...