详解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实现网页链接提取的方法分享
Feb 25 Python
python数据处理实战(必看篇)
Jun 11 Python
Python操作csv文件实例详解
Jul 31 Python
Python排序算法实例代码
Aug 10 Python
Python基于回溯法子集树模板解决选排问题示例
Sep 07 Python
Python操作Excel插入删除行的方法
Dec 10 Python
Python的形参和实参使用方式
Dec 24 Python
python numpy库linspace相同间隔采样的实现
Feb 25 Python
Python threading.local代码实例及原理解析
Mar 16 Python
pytorch VGG11识别cifar10数据集(训练+预测单张输入图片操作)
Jun 24 Python
Python 实现PS滤镜的旋涡特效
Dec 03 Python
Python字符串常规操作小结
Apr 03 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获取指定日期之间的各个周和月的起止时间
2014/11/24 PHP
php获取Google机器人访问足迹的方法
2015/04/15 PHP
Laravel框架在本地虚拟机快速安装的方法详解
2018/06/11 PHP
asp 的 分词实现代码
2007/05/24 Javascript
点图片上一页下一页翻页效果
2008/07/09 Javascript
JavaScript DOM学习第一章 W3C DOM简介
2010/02/19 Javascript
js 实现在离开页面时提醒未保存的信息(减少用户重复操作)
2013/01/16 Javascript
JavaScript中的object转换函数toString()与valueOf()介绍
2014/12/31 Javascript
浅谈JavaScript中的作用域和闭包问题
2015/07/07 Javascript
JS实现兼容性较好的随屏滚动效果
2015/11/09 Javascript
JQuery.Ajax()的data参数类型实例详解
2015/11/20 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
关于session和cookie的简单理解
2016/06/08 Javascript
老生常谈JavaScript 函数表达式
2016/09/01 Javascript
socket.io实现在线群聊功能
2017/04/07 Javascript
详解node-ccap模块生成captcha验证码
2017/07/01 Javascript
微信小程序实现轮播图效果
2017/09/07 Javascript
vue 实现 ios 原生picker 效果及实现思路解析
2017/12/06 Javascript
使用Vuex解决Vue中的身份验证问题
2018/09/28 Javascript
浅谈layui 表单元素的选中问题
2019/10/25 Javascript
element-ui tooltip修改背景颜色和箭头颜色的实现
2019/12/16 Javascript
[01:56]生活中的妖精之七夕特别档
2016/08/09 DOTA
python网络爬虫学习笔记(1)
2018/04/09 Python
十分钟利用Python制作属于你自己的个性logo
2018/05/07 Python
PyQt5 QTable插入图片并动态更新的实例
2019/06/18 Python
Python实现 PS 图像调整中的亮度调整
2019/06/28 Python
Python寻找路径和查找文件路径的示例
2019/07/10 Python
解决Django Static内容不能加载显示的问题
2019/07/28 Python
Tensorflow中tf.ConfigProto()的用法详解
2020/02/06 Python
python如何快速拼接字符串
2020/10/28 Python
用canvas显示验证码的实现
2020/04/10 HTML / CSS
Sneaker Studio匈牙利:购买运动鞋
2018/03/26 全球购物
新闻系毕业生推荐信
2013/11/16 职场文书
大学三年的自我评价
2013/12/25 职场文书
农民工工资支付承诺书
2015/05/04 职场文书
Python中Numpy和Matplotlib的基本使用指南
2021/11/02 Python