Python标准库模块之heapq – 堆构造

读前福利:几百本经典书籍https://www.johngo689.com/2158/

原文链接:https://www.johngo689.com/2264/

堆作为优先队列的常用方法,而且在数据结构和算法方面,经常使用大顶堆和小顶堆进行问题的解决。

使用 Python 提供的标准库heapq

import heapq

注意:默认的堆结构是小顶堆

一、构造堆 & 获取最小值

方法一:创建空列表,然后手动加入元素

heapq.heappush()

举例:

>>> nums = [2, 5, 1, 6, 9, 0]
>>> heap = []
>>> for num in nums:
... heapq.heappush(heap, num)
...
>>> print(heap[0])
0
>>> print([heapq.heappop(heap) for _ in range(len(nums))])
[0, 1, 2, 5, 6, 9]

方法二:初始化 list,然后转为堆结构

heapq.heapify(list)

直接将 list 转为堆结构

举例:

>>> nums = [2, 5, 1, 6, 9, 0]
>>> # 转为heap结构
...
>>> heap.heapify(nums)
>>> print(nums[0])
0
>>> print([heapq.heappop(nums) for _ in range(len(nums))])
[0, 1, 2, 5, 6, 9]

删除最小值 并且 加入新元素, 使用heapq.heaprepalce()

>>> nums = [2, 5, 1, 6, 9, 0]
>>> # 转为heap结构
...
>>> heap.heapify(nums)
>>> heapq.heapreplace(nums, 100)
0
>>> heapq.heapreplace(nums, -1)
1
>>> print([heapq.heappop(nums) for _ in range(len(nums))])
[-1, 2, 5, 6, 9, 100]

二、获取最大值

这里没有直接构造大顶堆的方法,可以使用一个很巧妙的思路进行解决。

这是一个很 Tirck 的思路:

首先我们用上述方法一进行构造堆结构,注意要在每一个元素增加一个负号(-):

>>> nums
[0, 5, 1, 6, 9, 2]
>>> nums = [2, 5, 1, 6, 9, 0]
>>> heap = []
>>> for num in nums:
... heapq.heappush(heap, -num)
>>> heap
[-9, -6, -1, -2, -5, 0]

接下来,打印堆元素,注意也要加负号(-):

>>> print([-heapq.heappop(heap) for _ in range(len(nums))])
[9, 6, 5, 2, 1, 0]

这样是不是就巧妙的将大顶堆进行打印出来了。

整体思路:push(-) -> pop(-),负负得正。

三、获取最小值和最大值的范围

获取堆中最大或最小的范围值。

使用heapq.nlargest()heapq.nsmallest() 函数进行求得:

>>> nums = [2, 5, 1, 6, 9, 0]
>>> heapq.heapify(nums)
>>> heapq.nlargest(3, nums)
[9, 6, 5]
>>> heapq.nsmallest(3, nums)
[0, 1, 2]

这个比较简单,需要主要添加范围值。

Python标准库模块之heapq – 堆构造的更多相关文章

  1. 【python标准库模块一】时间模块time学习

    本文介绍python的标准库模块time的常见用法 时间模块time 导入时间模块 import time 得到时间戳,这是统计从1970年1月1日0点0分到现在经过了多少秒,一般用于加减法一起用,比 ...

  2. 【python标准库模块五】Xml模块学习

    Xml模块 xml本身是一种格式规范,是一种包含了数据以及数据说明的文本格式规范.在json没有兴起之前各行各业进行数据交换的时候用的就是这个.目前在金融行业也在广泛在运用. 举个简单的例子,xml是 ...

  3. 【python标准库模块四】Json模块和Pickle模块学习

    Json模块 原来有个eval函数能能够从字符串中提取出对应的数据类型,比如"{"name":"zhangsan"}",可以提取出一个字典. ...

  4. 【python标准库模块三】Os模块和Sys模块学习

    Os模块 导入os模块 import os 获取当前工作目录 os.getcwd() 切换目录,跟linux中的cd一样 os.chdir("文件夹名") 递归生成文件夹 os.m ...

  5. 【python标准库模块二】random模块学习

    random模块是用来生成随机数的模块 导入random模块 import random 生成一个0~1的随机数,浮点数 #随机生成一个0~1的随机数 print(random.random()) 生 ...

  6. Python标准库笔记(11) — Operator模块

    Operator--标准功能性操作符接口. 代码中使用迭代器时,有时必须要为一个简单表达式创建函数.有些情况这些函数可以用一个lambda函数实现,但是对于某些操作,根本没必要去写一个新的函数.因此o ...

  7. Python标准库笔记(10) — itertools模块

    itertools 用于更高效地创建迭代器的函数工具. itertools 提供的功能受Clojure,Haskell,APL和SML等函数式编程语言的类似功能的启发.它们的目的是快速有效地使用内存, ...

  8. [python标准库]Pickle模块

    Pickle-------python对象序列化 本文主要阐述以下几点: 1.pickle模块简介 2.pickle模块提供的方法 3.注意事项 4.实例解析 1.pickle模块简介 The pic ...

  9. [python标准库]XML模块

    1.什么是XML XML是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分.您可以创建内容,然后使用限定标记标记它,从而使每个单词. ...

随机推荐

  1. java和js中for循环的区别

    java中for循环,先执行语句后循环 for (int i=1;i<10;i++){ for(int b=1;b<=i;b++){ System.out.print(b+"*& ...

  2. 解锁 VS Code 更多可能性,轻松入门 WebView

    作者:HelloGitHub-小夏 说起 VS Code 大家普遍印象应该都差不多是这样:不就是个编辑器嘛,最主要的还是 coding 的快感咯. 里面很多功能都应该是围绕如何提高 coding 效率 ...

  3. WIN10 64bit + QT5.10.0(MinGW3.5.0) + OpenCV3.4.1 无痛安装、配置

    安装QT和配置MinGW 官方下载qt-opensource-windows-x86-5.10.0.exe 正常步骤安装QT5.10.0,安装过程选择自带的MinGW3.5.0编译器即可. 打开QtC ...

  4. MySQL-SQL基础-子查询

    #子查询-某些情况下,当进行查询的时候,需要的条件是另外一个select语句的结果,这个时候就要用到子查询.用于子查询的关键字主要包括: in.not in.=.!=.exists.not exist ...

  5. 存储系统管理(三)——磁盘配额及lvm逻辑卷管理

    Linux是一个多用户的操作系统,系统有很多用户,就必须限制每个用户的保存空间,配额就是来管理用户空间的,配额只是针对与设备而言. 1.新建一个分区 2.格式化分区为xfs文件系统 3.将其以配额的方 ...

  6. Jest中Mock网络请求

    Jest中Mock网络请求 最近需要将一个比较老的库修改为TS并进行单元测试,修改为TS还能会一点,单元测试纯粹是现学现卖了,初学Jest框架,觉得在单元测试中比较麻烦的就是测试网络请求,所以记录一下 ...

  7. js实现钟表

    在网页上显示一个钟表 html: <body onload="startTime()"> <div id="txt"></div& ...

  8. 如何解决浮动元素高度塌陷---CSS

    解决高度塌陷问题的方法: 方法一. //给父元素添加声明 overflow:hidden; 缺点:回隐藏溢出的元素: 方法二. 在浮动的元素下添加空div标签,并给该元素添加声明: clear:bot ...

  9. scrum项目冲刺_day06总结

    摘要:今日完成任务. 1.服务器部署完成 2.由于将数据库放到了服务器上,搜索功能需要修改 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已完成) 2.语音识别功能(已完成 ...

  10. vscode快速添加引号 批量增加引号(用于批量格式化代码)

    一.在浏览器中将Params复制到pycharm的py文件中 二.选中需要添加引号的部分,Ctrl+H 调出替换工具栏 三.填写正则表达式 (.*?): (.*) '$1':'$2', 右侧注意点击使 ...