详解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中的内置函数getattr()介绍及示例
Jul 20 Python
Python入门学习之字符串与比较运算符
Oct 12 Python
Python下载网络文本数据到本地内存的四种实现方法示例
Feb 05 Python
基于python log取对数详解
Jun 08 Python
python抓取网页内容并进行语音播报的方法
Dec 24 Python
Python绘制堆叠柱状图的实例
Jul 09 Python
使用python动态生成波形曲线的实现
Dec 04 Python
如何基于python操作json文件获取内容
Dec 24 Python
Python selenium模拟手动操作实现无人值守刷积分功能
May 13 Python
解决Pytorch自定义层出现多Variable共享内存错误问题
Jun 28 Python
PyTorch如何搭建一个简单的网络
Aug 24 Python
Python中递归以及递归遍历目录详解
Oct 24 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增删改查示例自己写的demo
2013/09/04 PHP
PHP实现对数组分页处理实例详解
2017/02/07 PHP
ThinkPHP框架实现数据增删改
2017/05/07 PHP
Aster vs Newbee BO5 第三场2.19
2021/03/10 DOTA
htm调用JS代码
2007/03/15 Javascript
JavaScript下利用fso判断文件是否存在的代码
2010/12/11 Javascript
jQuery队列操作方法实例
2014/06/11 Javascript
关于延迟加载JavaScript
2015/05/05 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
2015/05/09 Javascript
JS返回只包含数字类型的数组实例分析
2016/12/16 Javascript
angular仿支付宝密码框输入效果
2017/03/25 Javascript
jQuery选择器之子元素选择器详解
2017/09/18 jQuery
thinkjs 文件上传功能实例代码
2017/11/08 Javascript
详解extract-text-webpack-plugin 的使用及安装
2018/06/12 Javascript
Vue中图片Src使用变量的方法
2019/10/30 Javascript
基于Vue实现微前端的示例代码
2020/04/24 Javascript
uniapp电商小程序实现订单30分钟倒计时
2020/11/01 Javascript
Python语言实现机器学习的K-近邻算法
2015/06/11 Python
Python探索之ModelForm代码详解
2017/10/26 Python
利用python3随机生成中文字符的实现方法
2017/11/24 Python
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
python3写的简单本地文件上传服务器实例
2018/06/04 Python
python读取和保存图片5种方法对比
2018/09/12 Python
Python的UTC时间转换讲解
2019/02/26 Python
Python实现KNN(K-近邻)算法的示例代码
2019/03/05 Python
Python pexpect模块及shell脚本except原理解析
2020/08/03 Python
python爬虫请求头的使用
2020/12/01 Python
竞选班长演讲稿
2013/12/30 职场文书
班组长岗位职责范本
2014/01/05 职场文书
十佳护士获奖感言
2014/02/18 职场文书
医学生就业推荐表自我鉴定
2014/03/26 职场文书
五分钟演讲稿
2014/04/30 职场文书
个人授权委托书范本
2014/09/14 职场文书
Python爬取英雄联盟MSI直播间弹幕并生成词云图
2021/06/01 Python
Python+Appium自动化测试的实战
2021/06/30 Python
Vscode中SSH插件如何远程连接Linux
2022/05/02 Servers