heapq 是 python 的内置模块,源码位于 Lib/heapq.py ,该模块提供了基于堆的优先排序算法。

堆的逻辑结构就是完全二叉树,并且二叉树中父节点的值小于等于该节点的所有子节点的值。这种实现可以使用 heap[k] <= heap[2k+1] 并且 heap[k] <= heap[2k+2] (其中 k 为索引,从 0 开始计数)的形式体现,对于堆来说,最小元素即为根元素 heap[0]。

可以通过 list 对 heap 进行初始化,或者通过 api 中的 heapify 将已知的 list 转化为 heap 对象。

heapq 提供的函数方法

heapq.heappush(heap, item)

heapq.heappop(heap):返回 root 节点,即 heap 中最小的元素

heapq.heappushpop(heap, item):向 heap 中加入 item 元素,并返回 heap 中最小元素

heapq.heapify(x)

heapq.nlargest(n, iterable, key=None):返回可枚举对象中的 n 个最大值,并返回一个结果集 list,key 为对该结果集的操作

heapq.nsmallest(n, iterable, key=None):同上相反

demo

1. 通过 heapq api 对 list 进行排序

 def heapsort(iterable):
h = [] for i in iterable:
heapq.heappush(h, i) return [heapq.heappop(h) for i in range(len(h))] s = [3, 5, 1, 2, 4, 6, 0, 1]
print(heapsort(s))

输出如下

 [0, 1, 1, 2, 3, 4, 5, 6]

2. 通过 key,找出对象列表中 price 最小的一项

 portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
cheap = heapq.nsmallest(1, portfolio, key=lambda s: s['price'])
print(cheap)

输出如下

 [{'shares': 45, 'price': 16.35, 'name': 'YHOO'}]

 extend

上文讲到 heapq 是最小堆的实现,那么我们根据 heapq 的源码分析一下在 python 中如何通过 api 实现将 list 转化为最小堆(父节点的关键字比左右子节点都小)

可分为如下几步操作:

1. 从最后一个有子节点的元素开始,将这个父节点元素和其子节点看做一个单元

2. 在单元中,将两个子节点中较小的元素与父节点调换位置(不需要判断父节点和这个最小子节点的大小关系),通过这一步操作即可将这个单元变更为最小堆单元

3. 通过 while 循环可以将较小的元素向上推

 def heapilize_list(x):
n = len(x)
# 获取存在子节点的节点 index 列表,并对每个节点单元进行最小堆处理
for i in reversed(range(n // 2)):
raiseup_node(x, i) def put_down_node(heap, startpos, pos):
current_item = heap[pos]
# 判断单元中最小子节点与父节点的大小
while pos > startpos:
parent_pos = (pos - 1) >> 1
parent_item = heap[parent_pos] if current_item < parent_item:
heap[pos] = parent_item
pos = parent_pos
continue
break heap[pos] = current_item def raiseup_node(heap, pos):
heap_len = len(heap)
start_pos = pos
current_item = heap[pos]
left_child_pos = pos * 2 + 1 while left_child_pos < heap_len:
right_child_pos = left_child_pos + 1
# 将这个单元中的最小子节点元素与父节点元素进行位置调换
if right_child_pos < heap_len and not heap[left_child_pos] < heap[right_child_pos]:
left_child_pos = right_child_pos
heap[pos] = heap[left_child_pos]
pos = left_child_pos
left_child_pos = pos * 2 + 1
heap[pos] = current_item
put_down_node(heap, start_pos, pos) p = [4, 6, 2, 10, 1]
heapilize_list(p)
print(p)

输出如下

 [1, 6, 2, 10, 4]

Python系列之heapq内置模块的更多相关文章

  1. Python系列之Collections内置模块(1)

    collections 是 python 的内置模块,源码位于 Lib/collections/__init__.py ,该模块提供了通用的数据容器. deque 容器对象 通过 from colle ...

  2. Python系列之Collections内置模块(2)

    defaultdict 返回一个类 dict 的对象,defaultdict 是内置的 dict 类的子类. 如果访问 dict 未初始化的 key 值时,会抛出 KeyError 异常. s_tup ...

  3. python学习笔记之heapq内置模块

    heapq内置模块位于./Anaconda3/Lib/heapq.py,提供基于堆的优先排序算法 堆的逻辑结构就是完全二叉树,并且二叉树中父节点的值小于等于该节点的所有子节点的值.这种实现可以使用 h ...

  4. 总结整理 -- python系列

    python系列 python--基础学习(一)开发环境搭建,体验HelloWorld python--基础学习(二)判断 .循环.定义函数.继承.调用 python--基础学习(三)字符串单引号.双 ...

  5. 初探接口测试框架--python系列7

    点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...

  6. 初探接口测试框架--python系列2

    点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...

  7. 初探接口测试框架--python系列3

    点击标题下「微信」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是我们期 ...

  8. 初探接口测试框架--python系列4

    点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...

  9. 初探接口测试框架--python系列5

    点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...

随机推荐

  1. php smarty

     摘自:http://linux.chinaitlab.com/PHP/38324.html 刚开始接触模版引擎的 PHP 设计师,听到 Smarty 时,都会觉得很难.其实笔者也不例外,碰都不敢碰一 ...

  2. c++ builder 2009如何生成独立运行exe(转)

    参考资料:https://forums.codegear.com/thread.jspa?threadID=13559&tstart=703 查了很多网站资料,说得差不多,但是最后编译出来的还 ...

  3. UVa 11110 - Equidivisions

    题目大意:给一个n*n的矩阵,其中放置n个数字,判断四连通的相同数字的个数是否等于n. Flood fill,本来没什么,用dfs判断一下就可以了,可是用scanf读取输入时TLE了,然后看到别人说要 ...

  4. 用C#开发一个 UWP BLUETOOTH BLE 扫描APP

    什么是WINDOWS UWP UWP即Windows 10 中的Universal Windows Platform简称.即Windows通用应用平台,在Win 10 Mobile/Surface(W ...

  5. bzoj1113

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1113 题解:单调栈 代码: #include<iostream> #includ ...

  6. 谈谈字符集编码及gb2312、utf-8编码原理

    一.基础中的基础比特位即bit,是计算机最小的存储单位.以0或1来表示比特位的值.Byte是字节数,bit是位数,在计算机中每八位为一字节,也就是1Byte=8bit:Byte和bit都翻译成比特,俗 ...

  7. JAVA 遍历文件夹下的所有文件(递归调用和非递归调用)

    JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...

  8. mysql存储过程中in、out、inout参数使用实际案例

    1.参数in的使用(代表输入,意思说你的参数要传到存过过程的过程里面去)//为了避免存储过程中分号(";")结束语句,我们使用分隔符告诉mysql解释器,该段命令是否已经结束了./ ...

  9. Java Me-List控件的用法案例

    /** * Java Me-List控件的用法案例 */package com.xushouwei.cn; import java.io.IOException;import javax.microe ...

  10. 腾讯面试题:10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。

    腾讯面试题:10G 个整数,乱序排列,要求找出中位数.内存限制为 2G. 题目和基本思路都来源网上,本人加以整理. 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只 ...