详解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 排列组合之itertools
Mar 20 Python
利用Python演示数型数据结构的教程
Apr 03 Python
Python 类的特殊成员解析
Jun 20 Python
Python logging模块用法示例
Aug 28 Python
Python3.7实现中控考勤机自动连接
Aug 28 Python
Python 实现Serial 与STM32J进行串口通讯
Dec 18 Python
基于Python3.7.1无法导入Numpy的解决方式
Mar 09 Python
基于打开pycharm有带图片md文件卡死问题的解决
Apr 24 Python
python中的测试框架
Nov 13 Python
python爬虫之爬取笔趣阁小说
Apr 22 Python
python flask框架快速入门
May 14 Python
Python 的演示平台支持 WSGI 接口的应用
Apr 20 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开发者的编程指南 第一部分降低复杂程度
2016/01/18 PHP
javascript indexOf函数使用说明
2008/07/03 Javascript
JavaScript 继承的实现
2009/07/09 Javascript
一些经常会用到的Javascript检测函数
2010/05/31 Javascript
复制Input内容的js代码_支持所有浏览器,修正了Firefox3.5以上的问题
2010/06/21 Javascript
EditPlus注册码生成器(js代码实现)
2013/03/25 Javascript
JQuery+Ajax无刷新分页的实例代码
2014/02/08 Javascript
jQuery获取iframe的document对象的方法
2014/10/10 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
javascript下拉列表中显示树形菜单的实现方法
2015/11/17 Javascript
js判断移动端是否安装某款app的多种方法
2015/12/18 Javascript
浅析$.getJSON异步请求和同步请求
2016/06/06 Javascript
基于Phantomjs生成PDF的实现方法
2016/11/07 Javascript
jQuery html表格排序插件tablesorter使用方法详解
2017/02/10 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
2018/01/12 Javascript
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
2019/11/18 NodeJs
vue实现购物车的监听
2020/04/20 Javascript
[01:44]Ti10举办地公布
2019/08/25 DOTA
Python中的多行注释文档编写风格汇总
2016/06/16 Python
python实现一个简单的并查集的示例代码
2018/03/19 Python
numpy.transpose对三维数组的转置方法
2018/04/17 Python
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
解决torch.autograd.backward中的参数问题
2020/01/07 Python
Python基于codecs模块实现文件读写案例解析
2020/05/11 Python
Python脚本如何在bilibili中查找弹幕发送者
2020/06/04 Python
python3读取autocad图形文件.py实例
2020/06/05 Python
Python调用C语言程序方法解析
2020/07/07 Python
python try...finally...的实现方法
2020/11/25 Python
巴西最大的体育用品商城:Netshoes巴西
2016/11/29 全球购物
用Python匹配HTML tag的时候,<.*>和<.*?>有什么区别
2012/11/04 面试题
设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
2014/12/30 面试题
小学家长评语大全
2014/04/16 职场文书
离婚协议书的范本
2015/01/27 职场文书
小爸爸观后感
2015/06/15 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书
前端实现滑动按钮AJAX与后端交互的示例代码
2022/02/24 Javascript