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. python运算符,内置函数简单使用

    1.编写程序,输入任意大的自然数,输出各位数字之和. 2.编写程序,输入两个集合 setA 和 setB,分别输出它们的交集.并集和差集 setA-setB. 3.编写程序,输入一个自然数,输出它的二 ...

  2. 关于struts中Ognl和iterator配合再次理解

    Person.jsp (struts.xml中省略) package com.mzy.entity; public class Person { private String name; privat ...

  3. Struts2框架基本使用

    时间:2017-1-6 16:53 修改struts.xml配置文件不需要重启服务器.Struts2框架    一.        *   介绍Struts2        *   关于Struts2 ...

  4. mysql主要的两个索引Innodb和MyIASM。

    参考:https://www.cnblogs.com/xiaohaillong/p/6079551.html 1. a.Innodb引擎,Innodb引擎提供了对数据库ACID事务的支持.并且还提供了 ...

  5. Ubuntu16.04 Linux 下无痛安装、配置Gogs

    本文在Win7+VMware的ubuntu 16.04中测试,安装Gogs,Install from binary. 准备工作: sudo apt-get install git sudo addus ...

  6. Java反射的浅显理解

    一.回顾反射相关的知识 1.在xml文件中使用反射的好处: 1)代码更加灵活,后期维护只需要修改配置文件即可 · 初学者一般习惯于在代码本身上直接修改,后期也可以修改配置文件达到相同的目的 · 修改配 ...

  7. 微前端框架single-spa初探

    前言 最近入职的一家公司采用single-spa这个微前端框架,所以自学了此框架. single-spa这个微前端框架虽然有中文文档,但是有些零散和晦涩. 所以我想在学习之余,写篇博客拉平一下这个学习 ...

  8. noip模拟测试18

    打开比赛第一眼--超级树? 点开--原题 百感交集-- 欣喜于发现是半年前做过两遍的原题 紧张于如果A不了比较尴尬 绝望于发现根本不会做了 瞟了一眼t1,瞅了一眼t2,嗯--开始搞t3 10分钟打完暴 ...

  9. echo -e 命令详解

    echo在php中是输入那么在linux中是不是也是输入呢,当然echo在linux也是输入不过它的用法比php强大多了可以带参数及一些东西,下面我们来看一篇关于linux echo命令介绍及-n.- ...

  10. 使用Redis Stream来做消息队列和在Asp.Net Core中的实现

    写在前面 我一直以来使用redis的时候,很多低烈度需求(并发要求不是很高)需要用到消息队列的时候,在项目本身已经使用了Redis的情况下都想直接用Redis来做消息队列,而不想引入新的服务,kafk ...