详解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使用xmlrpclib模块实现对百度google的ping功能
Jun 02 Python
python实现计算倒数的方法
Jul 11 Python
使用Python的Tornado框架实现一个Web端图书展示页面
Jul 11 Python
Python基于whois模块简单识别网站域名及所有者的方法
Apr 23 Python
用python生成1000个txt文件的方法
Oct 25 Python
Python中查看变量的类型内存地址所占字节的大小
Jun 26 Python
简单了解python反射机制的一些知识
Jul 13 Python
Pytorch DataLoader 变长数据处理方式
Jan 08 Python
Python换行与不换行的输出实例
Feb 19 Python
使用keras实现孪生网络中的权值共享教程
Jun 11 Python
Python如何读取、写入JSON数据
Jul 28 Python
Python读取Excel一列并计算所有对象出现次数的方法
Sep 04 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/12/13 PHP
PHP项目开发中最常用的自定义函数整理
2010/12/02 PHP
深入密码加salt原理的分析
2013/06/06 PHP
smarty模板判断数组为空的方法
2015/06/10 PHP
py文件转exe时包含paramiko模块出错解决方法
2016/08/12 PHP
PHP判断数组是否为空的常用方法(五种方法)
2017/02/08 PHP
Yii2使用表单上传文件的实例代码
2017/08/03 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
PHP接口类(interface)的定义、特点和应用示例
2020/05/18 PHP
PHP超全局变量实现原理及代码解析
2020/09/01 PHP
js跨域和ajax 跨域问题的实现思路
2009/09/05 Javascript
jquery实现的元素的left增加N像素 鼠标移开会慢慢的移动到原来的位置
2010/03/21 Javascript
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
2010/10/20 Javascript
document.getElementBy(&quot;id&quot;)与$(&quot;#id&quot;)有什么区别
2013/09/22 Javascript
javascript动态判断html元素并执行不同的操作
2014/06/16 Javascript
JQuery调用绑定click事件的3种写法
2015/03/28 Javascript
基于JavaScript代码实现随机漂浮图片广告
2016/01/05 Javascript
JS经典正则表达式笔试题汇总
2016/12/15 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
js中的触发事件对象event.srcElement与event.target详解
2017/03/15 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
基于VUE移动音乐WEBAPP跨域请求失败的解决方法
2018/01/16 Javascript
vue中实现在外部调用methods的方法(推荐)
2018/02/08 Javascript
Python SMTP配置参数并发送邮件
2020/06/16 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
Python使用socket模块实现简单tcp通信
2020/08/18 Python
python re.match()用法相关示例
2021/01/27 Python
Timex手表官网:美国运动休闲手表品牌
2017/01/28 全球购物
Tory Burch英国官方网站:美国时尚生活品牌
2017/12/06 全球购物
音乐学个人的自荐书范文
2013/11/26 职场文书
高中生学习生活的自我评价
2013/11/27 职场文书
资产经营总监岗位职责
2013/12/04 职场文书
日语求职信范文
2013/12/17 职场文书
小学红领巾中秋节广播稿
2014/01/13 职场文书
2015年项目经理工作总结
2015/04/30 职场文书
python标准库ElementTree处理xml
2022/05/20 Python