详解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文件比较示例分享
Jan 10 Python
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 Python
[原创]教女朋友学Python(一)运行环境搭建
Nov 29 Python
python 实现数组list 添加、修改、删除的方法
Apr 04 Python
python 实现登录网页的操作方法
May 11 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
May 28 Python
python3实现windows下同名进程监控
Jun 21 Python
Python中查看变量的类型内存地址所占字节的大小
Jun 26 Python
浅谈Pandas Series 和 Numpy array中的相同点
Jun 28 Python
python 等差数列末项计算方式
May 03 Python
六种酷炫Python运行进度条效果的实现代码
Jul 17 Python
利用python做表格数据处理
Apr 13 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中执行系统外部命令
2006/10/09 PHP
php 文章采集正则代码
2009/12/28 PHP
深入php socket的讲解与实例分析
2013/06/13 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
根据分辨率不同,调用不同的css文件
2006/07/07 Javascript
非常强大的 jQuery.AsyncBox 弹出对话框插件
2011/08/29 Javascript
js中function()使用方法
2013/12/24 Javascript
Javascript中innerHTML用法实例分析
2015/01/12 Javascript
Bootstrap3制作搜索框样式的方法
2016/07/11 Javascript
用原生JS对AJAX做简单封装的实例代码
2016/07/13 Javascript
分享一道关于闭包、bind和this的面试题
2017/02/20 Javascript
JS数组操作中的经典算法实例讲解
2017/07/26 Javascript
Angular4学习教程之DOM属性绑定详解
2018/01/04 Javascript
详解ES6语法之可迭代协议和迭代器协议
2018/01/13 Javascript
vue iview组件表格 render函数的使用方法详解
2018/03/15 Javascript
vue 实现走马灯效果
2019/10/28 Javascript
vue 如何从单页应用改造成多页应用
2020/10/23 Javascript
javascript实现倒计时提示框
2021/03/02 Javascript
[44:33]EG vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python time模块详解(常用函数实例讲解,非常好)
2014/04/24 Python
django自定义Field实现一个字段存储以逗号分隔的字符串
2014/04/27 Python
python数据结构之二叉树的建立实例
2014/04/29 Python
Python的Bottle框架的一些使用技巧介绍
2015/04/08 Python
Python实现的使用telnet登陆聊天室实例
2015/06/17 Python
python操作mysql数据库
2017/03/05 Python
python 类详解及简单实例
2017/03/24 Python
详解Python判定IP地址合法性的三种方法
2018/03/06 Python
详解python中Numpy的属性与创建矩阵
2018/09/10 Python
python爬取网易云音乐评论
2018/11/16 Python
pytorch 修改预训练model实例
2020/01/18 Python
幼儿园大班毕业教师寄语
2014/04/03 职场文书
纪念九一八事变演讲稿:勿忘国耻
2014/09/14 职场文书
党员批评与自我批评发言稿
2014/10/14 职场文书
2015国庆节感想
2015/08/04 职场文书
导游词之鲁迅祖居
2019/10/17 职场文书
巧用 -webkit-box-reflect 倒影实现各类动效(小结)
2021/04/22 HTML / CSS