详解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绘图库Matplotlib的安装
Jul 03 Python
Python的面向对象思想分析
Jan 14 Python
Django中的“惰性翻译”方法的相关使用
Jul 27 Python
python实现发送邮件及附件功能
Mar 02 Python
python实现对指定输入的字符串逆序输出的6种方法
Apr 26 Python
Python自定义一个类实现字典dict功能的方法
Jan 19 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 Python
python如何进行矩阵运算
Jun 05 Python
使用已经得到的keras模型识别自己手写的数字方式
Jun 29 Python
Python通过递归函数输出嵌套列表元素
Oct 15 Python
python编写扎金花小程序的实例代码
Feb 23 Python
Python中rapidjson参数校验实现
Jul 25 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集成FCK的函数代码
2008/09/27 PHP
fleaphp crud操作之findByField函数的使用方法
2011/04/23 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
PHP实现函数内修改外部变量值的方法示例
2018/12/28 PHP
IE和FireFox(FF)中js和css的不同
2009/04/13 Javascript
关于js拖拽上传 [一个拖拽上传修改头像的流程]
2011/07/13 Javascript
jquery ajax return没有返回值的解决方法
2011/10/20 Javascript
使用JavaScript动态设置样式实现代码及演示动画
2013/01/25 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
js控制再次点击按钮之间的间隔时间可防止重复提交
2014/08/01 Javascript
js为什么不能正确处理小数运算?
2015/12/29 Javascript
jQuery AjaxUpload 上传图片代码
2016/02/02 Javascript
JS中的二叉树遍历详解
2016/03/18 Javascript
JavaScript使用FileReader实现图片上传预览效果
2020/03/27 Javascript
vue-router2.0 组件之间传参及获取动态参数的方法
2017/11/10 Javascript
JS 验证码功能的三种实现方式
2018/11/26 Javascript
利用JS响应式修改vue实现页面的input值
2019/09/02 Javascript
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
原生JS实现pc端轮播图效果
2020/12/21 Javascript
python动态性强类型用法实例
2015/05/09 Python
简单介绍Python中的round()方法
2015/05/15 Python
Python爬取十篇新闻统计TF-IDF
2018/01/03 Python
对python 各种删除文件失败的处理方式分享
2018/04/24 Python
Python DataFrame 设置输出不显示index(索引)值的方法
2018/06/07 Python
Windows下安装Scrapy
2018/10/17 Python
Python 使用 attrs 和 cattrs 实现面向对象编程的实践
2019/06/12 Python
pytorch梯度剪裁方式
2020/02/04 Python
英国的知名精品百货公司:House of Fraser(福来德)
2016/08/14 全球购物
什么是静态路由,其特点是什么?什么是动态路由,其特点是什么?
2013/07/26 面试题
如何写一份好的英文求职信
2014/03/19 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
2015年学校减负工作总结
2015/05/19 职场文书
山楂树之恋观后感
2015/06/11 职场文书
纪检干部学习心得体会
2016/01/23 职场文书
python缺失值的解决方法总结
2021/06/09 Python
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis