详解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处理python编码问题
Mar 13 Python
Python实现冒泡,插入,选择排序简单实例
Aug 18 Python
Python中让MySQL查询结果返回字典类型的方法
Aug 22 Python
详解Python操作RabbitMQ服务器消息队列的远程结果返回
Jun 30 Python
Python实现将Excel转换为json的方法示例
Aug 05 Python
详解python eval函数的妙用
Nov 16 Python
python命名空间(namespace)简单介绍
Aug 10 Python
关于Pytorch MaxUnpool2d中size操作方式
Jan 03 Python
python+selenium+PhantomJS抓取网页动态加载内容
Feb 25 Python
Python使用ElementTree美化XML格式的操作
Mar 06 Python
关于python3.7安装matplotlib始终无法成功的问题的解决
Jul 28 Python
python tqdm实现进度条的示例代码
Nov 10 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
php解析html类库simple_html_dom(详细介绍)
2013/07/05 PHP
jQuery 常见操作实现方式和常用函数方法总结
2011/05/06 Javascript
遨游,飞飞,IE,空中网 浏览器无提示关闭方法
2011/07/11 Javascript
jquery鼠标滑过提示title具体实现代码
2013/08/06 Javascript
一个JavaScript去除字符串末尾的空白实例代码
2014/09/22 Javascript
javascript使用闭包模拟对象的私有属性和方法
2016/10/05 Javascript
利用yarn实现一个webpack+react种子
2016/10/25 Javascript
利用Js+Css实现折纸动态导航效果实例源码
2017/01/25 Javascript
JS实现动态修改table及合并单元格的方法示例
2017/02/20 Javascript
angularJS深拷贝详解
2017/03/23 Javascript
微信小程序页面间通信的5种方式
2017/03/31 Javascript
jQuery实现按比例缩放图片的方法
2017/04/29 jQuery
React-router中结合webpack实现按需加载实例
2017/05/25 Javascript
Angular2进阶之如何避免Dom误区
2018/04/02 Javascript
微信小程序开发之tabbar图标和颜色的实现
2018/10/17 Javascript
解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
2019/10/11 Javascript
JavaScript实现刮刮乐效果
2020/11/01 Javascript
python利用beautifulSoup实现爬虫
2014/09/29 Python
python实现调用其他python脚本的方法
2014/10/05 Python
Python实现识别手写数字 Python图片读入与处理
2020/03/23 Python
Python用于学习重要算法的模块pygorithm实例浅析
2018/08/16 Python
Python 编程速成(推荐)
2019/04/15 Python
Python networkx包的实现
2020/02/14 Python
Python+Django+MySQL实现基于Web版的增删改查的示例代码
2020/05/13 Python
3分钟看懂Python后端必须知道的Django的信号机制
2020/07/26 Python
python爬虫用request库处理cookie的实例讲解
2021/02/20 Python
html5 的a标签 Href 拨电话的写法
2013/11/04 HTML / CSS
五个2015 年最佳HTML5 框架
2015/11/11 HTML / CSS
html5中audio支持音频格式的解决方法
2018/08/24 HTML / CSS
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
申报职称专业技术个人的自我评价
2013/12/12 职场文书
《小儿垂钓》教学反思
2014/02/23 职场文书
单位租房协议书样本
2014/10/30 职场文书
2015年高中生国庆节演讲稿
2015/07/30 职场文书
小学班级口号大全
2015/12/25 职场文书
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis