详解Python中heapq模块的用法


Posted in Python onJune 28, 2016

heapq 模块提供了堆算法。heapq是一种子节点和父节点排序的树形数据结构。这个模块提供heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2]。为了比较不存在的元素被人为是无限大的。heap最小的元素总是[0]。

打印 heapq 类型

import math 
import random
from cStringIO import StringIO

def show_tree(tree, total_width=36, fill=' '):
   output = StringIO()
   last_row = -1
   for i, n in enumerate(tree):
     if i:
       row = int(math.floor(math.log(i+1, 2)))
     else:
       row = 0
     if row != last_row:
       output.write('\n')
     columns = 2**row
     col_width = int(math.floor((total_width * 1.0) / columns))
     output.write(str(n).center(col_width, fill))
     last_row = row
   print output.getvalue()
   print '-' * total_width
   print 
   return

data = random.sample(range(1,8), 7)
print 'data: ', data
show_tree(data)

打印结果

data: [3, 2, 6, 5, 4, 7, 1]

     3           
  2      6      
5    4  7     1   
-------------------------
heapq.heappush(heap, item)

push一个元素到heap里, 修改上面的代码

heap = []
data = random.sample(range(1,8), 7)
print 'data: ', data

for i in data:
  print 'add %3d:' % i
  heapq.heappush(heap, i)
  show_tree(heap)

打印结果

data: [6, 1, 5, 4, 3, 7, 2]
add  6:
         6         
 ------------------------------------
add  1:
      1 
   6         
------------------------------------
add  5:
      1 
   6       5       
------------------------------------
add  4:
        1 
    4       5       
  6
------------------------------------
add  3:
        1 
    3       5       
  6    4
------------------------------------
add  7:
        1 
    3        5       
  6    4    7
------------------------------------
add  2:
        1 
    3        2       
  6    4    7    5
------------------------------------

根据结果可以了解,子节点的元素大于父节点元素。而兄弟节点则不会排序。

heapq.heapify(list)

将list类型转化为heap, 在线性时间内, 重新排列列表。

print 'data: ', data
heapq.heapify(data)
print 'data: ', data

show_tree(data)

打印结果

data: [2, 7, 4, 3, 6, 5, 1]
data: [1, 3, 2, 7, 6, 5, 4]

      1         
   3         2     
7    6    5    4  
------------------------------------
heapq.heappop(heap)

删除并返回堆中最小的元素, 通过heapify() 和heappop()来排序。

data = random.sample(range(1, 8), 7)
print 'data: ', data
heapq.heapify(data)
show_tree(data)

heap = []
while data:
  i = heapq.heappop(data)
  print 'pop %3d:' % i
  show_tree(data)
  heap.append(i)
print 'heap: ', heap

打印结果

data: [4, 1, 3, 7, 5, 6, 2]

         1
    4         2
  7    5    6    3
------------------------------------

pop  1:
         2
    4         3
  7    5    6
------------------------------------
pop  2:
         3
    4         6
  7    5
------------------------------------
pop  3:
         4
    5         6
  7
------------------------------------
pop  4:
         5
    7         6
------------------------------------
pop  5:
         6
    7
------------------------------------
pop  6:
        7
------------------------------------
pop  7:

------------------------------------
heap: [1, 2, 3, 4, 5, 6, 7]

可以看到已排好序的heap。

heapq.heapreplace(iterable, n)

删除现有元素并将其替换为一个新值。

data = random.sample(range(1, 8), 7)
print 'data: ', data
heapq.heapify(data)
show_tree(data)

for n in [8, 9, 10]:
  smallest = heapq.heapreplace(data, n)
  print 'replace %2d with %2d:' % (smallest, n)
  show_tree(data)

打印结果

data: [7, 5, 4, 2, 6, 3, 1]

         1
    2         3
  5    6    7    4
------------------------------------

replace 1 with 8:

         2
    5         3
  8    6    7    4
------------------------------------

replace 2 with 9:

         3
    5         4
  8    6    7    9
------------------------------------

replace 3 with 10:

         4
    5         7
  8    6    10    9
------------------------------------

heapq.nlargest(n, iterable) 和 heapq.nsmallest(n, iterable)

返回列表中的n个最大值和最小值

data = range(1,6)
l = heapq.nlargest(3, data)
print l     # [5, 4, 3]

s = heapq.nsmallest(3, data)
print s     # [1, 2, 3]

PS:一个计算题
构建元素个数为 K=5 的最小堆代码实例:

#!/usr/bin/env python 
# -*- encoding: utf-8 -*- 
# Author: kentzhan 
# 
 
import heapq 
import random 
 
heap = [] 
heapq.heapify(heap) 
for i in range(15): 
 item = random.randint(10, 100) 
 print "comeing ", item, 
 if len(heap) >= 5: 
  top_item = heap[0] # smallest in heap 
  if top_item < item: # min heap 
   top_item = heapq.heappop(heap) 
   print "pop", top_item, 
   heapq.heappush(heap, item) 
   print "push", item, 
 else: 
  heapq.heappush(heap, item) 
  print "push", item, 
 pass 
 print heap 
pass 
print heap 
 
print "sort" 
heap.sort() 
 
print heap

结果:

详解Python中heapq模块的用法

Python 相关文章推荐
flask中使用SQLAlchemy进行辅助开发的代码
Feb 10 Python
Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器
Jun 04 Python
Python写的一个定时重跑获取数据库数据
Dec 28 Python
Python中支持向量机SVM的使用方法详解
Dec 26 Python
python中的迭代和可迭代对象代码示例
Dec 27 Python
numpy.random.seed()的使用实例解析
Feb 03 Python
详解Python中的动态属性和特性
Apr 07 Python
python绘制评估优化算法性能的测试函数
Jun 25 Python
python获取指定日期范围内的每一天,每个月,每季度的方法
Aug 08 Python
Python安装whl文件过程图解
Feb 18 Python
Django限制API访问频率常用方法解析
Oct 12 Python
pandas提升计算效率的一些方法汇总
May 30 Python
Python中operator模块的操作符使用示例总结
Jun 28 #Python
基础的十进制按位运算总结与在Python中的计算示例
Jun 28 #Python
Python中的with语句与上下文管理器学习总结
Jun 28 #Python
深入解析Python中的上下文管理器
Jun 28 #Python
详解Python中contextlib上下文管理模块的用法
Jun 28 #Python
实例讲解Python中SocketServer模块处理网络请求的用法
Jun 28 #Python
Python中asyncore异步模块的用法及实现httpclient的实例
Jun 28 #Python
You might like
thinkphp文件引用与分支结构用法实例
2014/11/26 PHP
PHP列出MySQL中所有数据库的方法
2015/03/12 PHP
PHP  Yii清理缓存的实现方法
2016/11/10 PHP
关于document.cookie的使用javascript
2010/10/29 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
javascript对中文按照拼音排序代码
2014/08/20 Javascript
js实现简单随机抽奖的方法
2015/01/27 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
Bootstrap模态对话框的简单使用
2016/04/29 Javascript
完美的js div拖拽实例代码
2016/09/24 Javascript
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
js中的数组对象排序分析
2018/12/11 Javascript
JS立即执行函数功能与用法分析
2019/01/15 Javascript
使用原生js编写一个简单的框选功能方法
2019/05/13 Javascript
Layui动态生成select下拉选择框不显示的解决方法
2019/09/24 Javascript
vue实现文字加密功能
2019/09/27 Javascript
React+Redux实现简单的待办事项列表ToDoList
2019/09/29 Javascript
vue项目中使用eslint+prettier规范与检查代码的方法
2020/01/16 Javascript
如何实现小程序与小程序之间的跳转
2020/11/04 Javascript
Python中使用Flask、MongoDB搭建简易图片服务器
2015/02/04 Python
连接Python程序与MySQL的教程
2015/04/29 Python
python 时间戳与格式化时间的转化实现代码
2016/03/23 Python
ubuntu安装mysql pycharm sublime
2018/02/20 Python
python算法与数据结构之单链表的实现代码
2019/06/27 Python
打印tensorflow恢复模型中所有变量与操作节点方式
2020/05/26 Python
python热力图实现简单方法
2021/01/29 Python
中科软笔试题和面试题
2014/10/07 面试题
户籍证明的格式
2014/01/13 职场文书
会计专业大学生求职信范文
2014/01/28 职场文书
党风廉政承诺书
2014/03/27 职场文书
单位证明范文
2015/06/18 职场文书
2016特色励志班级口号
2015/12/24 职场文书
MySQL 数据恢复的多种方法汇总
2021/06/21 MySQL
python小型的音频操作库mp3Play
2022/04/24 Python