详解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捕捉和模拟鼠标事件的方法
Jun 03 Python
Python脚本获取操作系统版本信息
Dec 17 Python
Python爬虫天气预报实例详解(小白入门)
Jan 24 Python
深入浅析Python的类
Jun 22 Python
django与小程序实现登录验证功能的示例代码
Feb 19 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
Sep 11 Python
Python 异常处理Ⅳ过程图解
Oct 18 Python
ubuntu 18.04 安装opencv3.4.5的教程(图解)
Nov 04 Python
pytorch标签转onehot形式实例
Jan 02 Python
pycharm不能运行.py文件的解决方法
Feb 12 Python
Python 随机生成测试数据的模块:faker基本使用方法详解
Apr 09 Python
python argparse模块通过后台传递参数实例
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实现的简易版图片相似度比较
2015/01/07 PHP
基于PHP的加载类操作以及其他两种魔术方法的应用实例
2017/08/28 PHP
利用PHPStorm如何开发Laravel应用详解
2017/08/30 PHP
JavaScript移除数组元素减少长度的方法
2013/09/05 Javascript
jQuery插件easyUI实现通过JS显示Dialog的方法
2016/09/16 Javascript
JS实现留言板功能[楼层效果展示]
2017/12/27 Javascript
AngularJS对动态增加的DOM实现ng-keyup事件示例
2018/03/12 Javascript
vue.js实现的经典计算器/科学计算器功能示例
2018/07/11 Javascript
vue项目中添加单元测试的方法
2018/07/21 Javascript
微信小程序实现日历功能
2018/11/27 Javascript
ant-design-vue 快速避坑指南(推荐)
2020/01/21 Javascript
Vue自定义组件双向绑定实现原理及方法详解
2020/09/03 Javascript
[05:43]VG.R战队教练Mikasa专访:为目标从未停止战斗
2016/08/02 DOTA
用pickle存储Python的原生对象方法
2017/04/28 Python
在Python web中实现验证码图片代码分享
2017/11/09 Python
python中os和sys模块的区别与常用方法总结
2017/11/14 Python
使用python实现语音文件的特征提取方法
2019/01/09 Python
python+openCV对视频进行截取的实现
2020/11/27 Python
纯css3实现的鼠标悬停动画按钮
2014/12/23 HTML / CSS
HTML5 播放 RTSP 视频的实例代码
2019/07/29 HTML / CSS
英国最大的女性服装零售商:Dorothy Perkins
2017/03/30 全球购物
Hotter Shoes英国官网:英伦风格,舒适的鞋子
2017/12/28 全球购物
英国自行车商店:AW Cycles
2021/02/24 全球购物
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2014/07/21 面试题
应届生文秘专业个人自荐信格式
2013/09/21 职场文书
办公室经理岗位职责
2014/01/01 职场文书
农贸市场管理制度
2014/01/31 职场文书
婚内房产协议书范本
2014/10/02 职场文书
党风廉政建设调研报告
2015/01/01 职场文书
家长对孩子的寄语
2015/02/26 职场文书
2016猴年开门红标语口号
2015/12/26 职场文书
新员工入职感言范文!
2019/07/04 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
python基础之函数的定义和调用
2021/10/24 Python
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技
pytest实现多进程与多线程运行超好用的插件
2022/07/15 Python