详解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 相关文章推荐
Python装饰器基础详解
Mar 09 Python
Python实现在线暴力破解邮箱账号密码功能示例【测试可用】
Sep 06 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
Feb 23 Python
Python利用正则表达式实现计算器算法思路解析
Apr 25 Python
pycharm运行出现ImportError:No module named的解决方法
Oct 13 Python
如何用Python做一个微信机器人自动拉群
Jul 03 Python
PyQt+socket实现远程操作服务器的方法示例
Aug 22 Python
Python通过Manager方式实现多个无关联进程共享数据的实现
Nov 07 Python
Python特殊属性property原理及使用方法解析
Oct 09 Python
Opencv+Python识别PCB板图片的步骤
Jan 07 Python
浅谈Python数学建模之整数规划
Jun 23 Python
python和anaconda的区别
May 06 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
VML绘图板②脚本--VMLgraph.js、XMLtool.js
2006/10/09 PHP
php 显示指定路径下的图片
2009/10/29 PHP
php购物车实现代码
2011/10/10 PHP
php+webSoket实现聊天室示例代码(附源码)
2017/02/17 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
2020/02/21 PHP
地震发生中逃生十大法则
2008/05/12 Javascript
Ext 表单布局实例代码
2009/04/30 Javascript
Javascript var变量隐式声明方法
2009/10/19 Javascript
JS Replace 全部替换字符的用法小结
2013/12/24 Javascript
Jquery的Tabs内容轮换效果实现代码,几行搞定
2014/02/12 Javascript
js简单设置与使用cookie的方法
2016/01/22 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
JavaScript实现的简单Tab点击切换功能示例
2018/07/06 Javascript
node.js之基础加密算法模块crypto详解
2018/09/11 Javascript
Vue安装浏览器开发工具的步骤详解
2019/05/12 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
2019/07/19 Javascript
Vue两个版本的区别和使用方法(更深层次了解)
2020/02/16 Javascript
python使用mailbox打印电子邮件的方法
2015/04/30 Python
pycharm中连接mysql数据库的步骤详解
2017/05/02 Python
Python实现的自定义多线程多进程类示例
2018/03/23 Python
Django如何配置mysql数据库
2018/05/04 Python
python 获取当天凌晨零点的时间戳方法
2018/05/22 Python
python os.fork() 循环输出方法
2019/08/08 Python
浅谈Python 敏感词过滤的实现
2019/08/15 Python
python3 中时间戳、时间、日期的转换和加减操作
2020/07/14 Python
Python  Asyncio模块实现的生产消费者模型的方法
2021/03/01 Python
优质有机椰子产品:Dr. Goerg
2019/09/24 全球购物
大学生预备党员自我评价分享
2013/11/16 职场文书
医大实习自我鉴定
2013/12/07 职场文书
公积金单位接收函
2014/01/11 职场文书
打架检讨书100字
2014/01/19 职场文书
幼儿园教学随笔感言
2014/02/23 职场文书
幼儿园教师安全责任书
2015/05/08 职场文书
2019入党申请书范文3篇
2019/08/21 职场文书
Python还能这么玩之用Python修改了班花的开机密码
2021/06/04 Python