Python高级操作第一弹:heapq的妙用

Python heapq库的用法介绍 阅读详情

1 基础操作

"""
1)基础:入堆、出堆、替换操作;heapq.heappush(heapq, item)/heapq.heappop(heapq, item)/
        .heappushpop(压入一个,弹出一个)/.heapreplace(先弹出堆顶,再压入元素,和heappushpop顺序相反)
   初始化:创建堆用[]的列表,或者heapify()来将填充的列表转化为堆
   操作:.merge(迭代对象,key,reverse)合并多个输入,.nlarget(n,迭代,key=none) .nsmallest(n) n小时候有效,n大时候用sorted()更好
2)heap 堆; 二叉堆 binary heap; Fibonacci heap; binomial heap 二项堆
3)更高级的:优先级堆(优先级队列实现方法);——一种二叉树;heap[k] <= heap[2k+1], heap[k] <= heap[2k+2]
     heap[0]始终是全堆最小的值(如果压入-element那么就反过来最大的值,百试不爽)
"""
from heapq import *
from typing import List

import numpy as np
import copy

# ex1:
hq = []
heappush(hq, (2,'play game'))
heappush(hq, (1,'play with son'))
heappush(hq, (3,'invite his mom'))
heappush(hq, (4,'go out for lunch'))
[print(heappop(hq)) for i in range(4)]

# ex2:
hq_n = [4,3,5,6,9,100,-100,-200]
heapify(hq_n)
[print(heappop(hq_n)) for i in range(len(hq_n))]

print("inverse sequence")
hq_inv = copy.deepcopy([4,3,5,6,9,100,-100,-200])
hq_inv = list(-np.array(hq_inv))
heapify(hq_inv)
[print(-heappop(hq_inv)) for i in range(len(hq_inv))]
"""
Output:

(1, 'play with son')
(2, 'play game')
(3, 'invite his mom')
(4, 'go out for lunch')
-200
-100
3
4
5
6
9
100
inverse sequence
100
9
6
5
4
3
-100
-200
"""
  • 这个玩意儿,简单一句话,就是用二叉树的方法实现了堆的树形结构,取用、排序稳定在O(nlogn)复杂度,最恶劣情况和平均情况相差无几;
  • 然而,对于很多头疼的情况,比如实际中的磁盘存储平衡等,解决得很是巧妙;
  • 这里碰到一个Leetcode第4题的期刊,对比下实现,喷了一口老血

2 LeetCode 004测试威力

2-1 title

“”"
LC04: 4. 寻找两个正序数组的中位数
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:

输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:

输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:

输入:nums1 = [2], nums2 = []
输出:2.00000
“”"

2-2 传统的合并数组,删除合并掉的,思路直接操作繁琐25行代码

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> None:
        rst = []
        if len(nums1) + len(nums2) == 0:
            return None

        while nums1 and nums2:
            if nums1[0] < nums2[0]:
                rst.append(nums1[0])
                del nums1[0]
            else:
                rst.append(nums2[0])
                del nums2[0]

        while nums1:
            rst.append(nums1[0])
            del nums1[0]

        while nums2:
            rst.append(nums2[0])
            del nums2[0]

        x = len(rst)
        # print(rst, x//2)

        if x / 2 != x // 2:
            return rst[x // 2]
        else:
            return (rst[x // 2 - 1] + rst[x // 2]) / 2

        # return np.mean(rst[int((len(rst)/2-1)) : int(len(rst)/2)+1])
        # (float( rst[int((len(rst)/2-1))]) + float(rst[int(len(rst)/2)+1]) ) /2
        #很直接的思路,逐个加入元素,删掉原有的,比较耗费;2)注意结尾的中位数取值和长度的奇偶有关

2-3 扣奇偶数,算序号,烧脑,40+行

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        # 不删除元素,只存取i j序号;取到总长度len/2的元素和前一个元素
        rst = None
        length = len(nums1) + len(nums2)
        if length == 0:
            return None

        i, j = len(nums1) - 1, len(nums2) - 1

        if length // 2 != length / 2:
            seq = length // 2 + 1  # 找到第seq + 1个元素
            while i >= 0 and j >= 0:
                if nums1[i] > nums2[j]:
                    rst = nums1[i]
                    i -= 1
                else:
                    rst = nums2[j]
                    j -= 1
                seq -= 1
                if seq == 0:
                    return rst
            while i >= 0:
                i -= 1
                seq -= 1
                if seq == 0:
                    return nums1[i + 1]
            while j >= 0:
                j -= 1
                seq -= 1
                if seq == 0:
                    return nums2[j + 1]
        else:
            seq = length // 2 + 1  # 找第seq,和seq-1
            rst = [0, 0]
            while i >= 0 and j >= 0:
                seq -= 1
                if nums1[i] > nums2[j]:
                    rst[seq % 2] = nums1[i]
                    i -= 1
                else:
                    rst[seq % 2] = nums2[j]
                    j -= 1

                if seq == 0:
                    return (rst[0] + rst[1]) / 2

            while i >= 0:
                seq -= 1
                rst[seq % 2] = nums1[i]
                i -= 1
                if seq == 0:
                    return (rst[0] + rst[1]) / 2

            while j >= 0:
                seq -= 1
                rst[seq % 2] = nums2[j]
                j -= 1
                if seq == 0:
                    return (rst[0] + rst[1]) / 2
            # 改良的思路,开销比上一个还大;

    # python高级知识第一弹:heapq操作,堆操作;简化存储,快速构建数据结构的有效操作!

2-4 堆方法,10行,两个list加起来heapify一下,输出前一半,然后取末尾1-2个做中位数

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        # 建立两个堆,分别存放小值和大值;保持两个堆size一致(最多相差1);
        #总数为偶数就找
        num = nums1 + nums2
        heapify(num)
        x = len(nums1) + len(nums2)
        if x == 0:
            return None

        L = nsmallest(x // 2 + 1, num)
        if x % 2: #奇数,x//2 + 1
            return max(L)
        else:
            return (L[-1] + L[-2])/2

Summary

  • 效果惊呆了
  • 只是heapify一下,然后nsmallest,或nlargest取出一半数就成; heappop和heappush,heapreplace,heappushpop都没有用上
Python中的heapq模块 我们可以将待排序的数据构建成一个小顶堆,每次从堆顶弹出数据,收集弹出的数据,这样我们就可以获得一个排完序的序列。,直接将可迭代的对象转换成小顶堆。有两种方法可以用于创建堆,第一种是直接使用方法。模块实现了堆队列的算法,即优先队列算法。方法返回的是当前堆中的最小元素。将元素手动放入指定的。 阅读详情

相关推荐

Python 模块之heapq

1、heapq介绍: 1)堆是非线性的树形的数据结构,有两种堆,最大堆与最小堆。(heapq库中的堆默认是最小堆) 最大堆,树种各个父节点的值总是大于或等于任何一个子节点的值。 最小堆,树种各个父节点的值总是小于或等于任何一个子节点的值。 2)堆是一个二叉树,其中最小堆每个父节点的值都小于或等于其所有子节点的值。整个最小堆的最小元素总是位于二叉树的根节点。 3)堆是用数组实现的二叉树,所以它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。 4)python的he.

sanmi8276的博客 3851

Python 基础 (标准库):heapq (堆)

Python 基础(标准库):堆 heap

AbigailQin 的博客 1万+

Python:使用 heapq 制作优先级队列

优先级队列是一种特殊的队列,其中每个元素都有一个优先级。队列中的元素按照优先级顺序排列,每次从队列中取出的都是具有最高优先级的元素。优先级队列广泛应用于各种场景,如任务调度、事件驱动模拟、图算法(如 Dijkstra 算法)等。heapq 是 Python 标准库中的一个模块,提供了实现最小堆(min heap)所需的各种函数。最小堆是一种特殊的完全二叉树,其中每个节点的值都不大于其子节点的值。最小堆非常适合用来实现优先级队列,因为堆顶元素始终是最小的元素,即具有最高优先级的元素。

7huaping的专栏 1493

python3中的heapq模块(堆排序)使用

heapq-堆排序算法:heapq实现了一个适合与Python的列表一起使用的最小堆排序算法。堆就是用数组表示的二叉树,分为大根堆和小根堆,大根堆为堆顶元素最大的堆,小根堆为堆顶元素最小的堆。

flyingluohaipeng的博客 9242

深入理解Python中的数据结构:heapq

Python的heapq模块提供了一组函数用于操作堆,其中所有函数都基于列表实现。通过heapq,你可以将列表当作堆来使用,而不是重新实现堆的数据结构。本文详细介绍了Python标准库中的heapq模块,包括其基本操作、高级用法和实际应用场景。通过heapq,你可以高效地实现优先级队列、堆排序以及各种算法,如Dijkstra和K路归并。尽管heapq实现的是最小堆,但通过简单的变通也可以实现最大堆。总的来说,heapq是一个非常强大且高效的工具,值得每一个Python开发者掌握。

weixin_71228606的博客 1233

Python编写平均中位数算法

在数据分析和统计学中,求解平均值和中位数是常见任务。在Python中,我们可以使用简单的代码实现这些算法。本文介绍了如何使用Python编写平均中位数算法,并提供了示例代码。读者可以根据自己的需求进行使用和修改。函数计算数字序列的中位数,先对数字序列进行排序,然后根据序列长度判断是取中间的数还是中间两个数的平均值。函数计算数字序列的平均值,使用了Python内置的。Python编写平均中位数算法。

PixelNovaO的博客 256

python中heapq堆的讲解

目录 堆结题的基本技巧: heapq堆的常用方法: heapq.heappush(heap, item) heapq.heapify(list) heapq.heappop(heap) heapq.heapreplace(heap.item) heapq.heappushpop(list,item) heapq.merge(…) heapq.nlargest(n,heap...

陈宸的博客 2万+

Python 妙用heapq

小顶堆求TopK大 大顶堆求BtmK小 题外话Python有一个内置的模块,heapq标准的封装了最小堆的算法实现。下面看两个不错的应用。小顶堆(求TopK大)话说需求是这样的: 定长的序列,求出TopK大的数据。import heapq import randomclass TopkHeap(object): def __init__(self, k): self.k =

更上一层楼! 8802

python高级(堆heapq模块)

一种著名的数据结构是堆(heap),它是一种优先队列。优先队列让你能够以任意顺序添加对象,并随时(可能是在两次添加对象之间)找出(并删除)最小的元素。相比于列表方法min,这样做的效率要高得多。 实际上,Python没有独立的堆类型,而只有一个包含一些堆操作函数的模块。这个模块名为heapq(其中的q表示队列),它包含6个函数,其中前4个与堆操作直接相关。必须使用列表来表示堆对象本身。 ...

jamfiy的博客 8万+

模型剪枝实战 | Torch-Pruning 库在YOLOv8上的应用指南

本文详细介绍了如何使用Torch-Pruning库对YOLOv8模型进行结构化剪枝,以实现模型“瘦身”。通过DepGraph(依赖图)技术自动处理层间依赖,确保剪枝安全。文章提供了从环境搭建、核心原理理解到完整剪枝流程的实战指南,并强调了剪枝后的微调与性能评估,帮助开发者在保持精度的同时显著提升模型推理速度。

weixin_29046035的博客 503

Cesium实战:5分钟搞定离线地图与地形加载(附避坑指南)

本文详细介绍了Cesium在内网环境下的离线部署实战方案,重点解决了影像与地形数据的本地加载问题。通过逐步指导项目配置、本地瓦片与自定义地形数据的处理,并优化相机控制体验,帮助开发者快速构建安全、高效的三维地球应用,避免常见的401错误与加载失败陷阱。

weixin_30632089的博客 281

Python中heapq模块浅析

Python提供了heapq模块,有利于我们更好的对堆的相关操作进行简化,下面总结我所用到的相关方法。 文章目录0 回顾堆的概念1 heappush(heap,item)建立大、小根堆2 heapify(heap)建立大、小根堆3 heappop(heap)3.1 利用heappop进行堆排序3.2 普通list的heapop()4 heappushpop(heap,item)5 heaprepl...

chandelierds的博客 5万+

innovus实战攻略 | 用setUsefulSkewMode解锁时序优化的“隐藏技能”!

就像时序优化的“瑞士军刀”,参数虽多,但掌握了分类逻辑后,用起来其实很简单!如果你有更绝的用法,欢迎在评论区分享,大家一起卷起来!简单来说,它就是时序优化的“乾坤大挪移”。通过调整触发器的时钟到达时间,把关键路径的建立时间“借”给非关键路径,从而实现全局时序收敛。别急,这个命令就是你的“时序救星”!(工具最多只能借1.2ns的裕量,防止“借过头”导致新问题!这个参数能帮你兜底!(对关键路径“下死手”,确保优化到位!(设置上限,给工具套上“紧箍咒”!(直接跳过边界,避免优化反噬!(全局管理,防止“借过头”!

weixin_50820814的博客 1355

Python精进系列:heapq 模块

Python heapq 模块是一个处理堆数据结构的强大工具。堆这种数据结构,以其独特的二叉树特性,在众多算法和数据处理场景中扮演着关键角色。

进一步有进一步的欢喜~ 2503

一种导弹追踪算法的MATLAB仿真实现

以下是一个用于模拟机动变轨导弹和防空导弹追踪过程的 MATLAB 代码,同时会提供 3D 效果展示。你可以运行这段代码,从而观察机动变轨导弹和防空导弹的速度与位置变化。

SmartGridequation的博客 935

统计信号处理基础 习题解答1-1

1-1:在雷达习题中,双程延时时间的估计量具有PDF τ0~Nτ0,στ02,其中τ0是真值。假如要估计距离请提出一种估计量R,并求它的PDF。然后,确定标准偏差στ0,使得距离估计值的99%在真值的100m以内,对电磁波传播速度取c=3×108m/s。 解答: 问题1: 由于电磁波传播速度c,信号可观察的双程传播延时τ0和双程传播距离τ0满足关系: R=cτ02 因此可采用如下估计量: R=cτ02 问题2: 由于τ0满足正态分布,且: Eτ0=τ0 varτ0=στ02 那么: E

weixin_43270276的博客 2806

Python模块之heapq

该模块提供了堆排序算法的实现。堆是二叉树,最大堆中父节点大于或等于两个子节点,最小堆父节点小于或等于两个子节点。 创建堆 heapq有两种方式创建堆, 一种是使用一个空列表,然后使用heapq.heappush()函数把值加入堆中,另外一种就是使用heap.heapify(list)转换列表成为堆结构 import heapq # 第一种 """ 函数定义: heapq.heappush(heap, item) - Push the value item onto the heap, ma

小贱的博客 1416

汽车软件工程师必看:ASPICE流程实战指南(附完整产物清单)

本文为汽车软件工程师提供ASPICE流程实战指南,详细解析如何搭建合规开发环境、各阶段文档产出清单及工具链整合策略。通过实战案例和模板资源,帮助团队高效实施ASPICE标准,提升软件开发质量与效率。

weixin_29230805的博客 470

Python笔记:heapq库简介

Python笔记:heapq库简介 1. heapq库是什么 2. 内置函数 3. heappop & heappush函数详细考察 1. heappush函数 2. heappop函数 4. 参考链接 1. heapq库是什么 heapq库算是一个黑科技,他在原理上并不复杂,事实上就是一个小顶堆结构,即将其转换为一个二叉树结构,则对于每一棵树而言,永远都有叶子节点的值大于根节点的值。 如此,我们只需要要在pop和push时维护好堆结构,就能够保证列表的第一个元素永远是最小的元素..

codename_cys的博客 4887

攻克低照度检测难题:YOLOv11主干网络增强新方案PE-YOLO详解

编码器部分# 解码器部分self.dec_conv2 = nn.Conv2d(512, 128, 3, padding=1) # 跳跃连接self.dec_conv3 = nn.Conv2d(256, 64, 3, padding=1) # 跳跃连接self.dec_conv4 = nn.Conv2d(128, 32, 3, padding=1) # 跳跃连接# 编码路径# 解码路径(带跳跃连接)

FJN110的博客 106

路径规划 | 图解RRT*算法(附ROS C++/Python/Matlab仿真)

RRT*算法针对传统RRT算法进行了渐进最优改进,在添加节点到搜索树的过程中进行重连选择。本文图解RRT*算法原理,并采用ROS C++、Python、Matlab三种语言实现算法,加深理解

FRIGIDWINTER的博客 9405

Python内置的heapq模块简析

Python内置的heapq模块        Python3.4版本中heapq包含了几个有用的方法: heapq.heappush(heap,item):将item,推入heap >>> items = [1,2,9,7,3] >>> heapq.heappush(items,10) >>> items [1, 2, 9, 7, 3, 10] >>>   heapq.heap

chuan_day的专栏 8396

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

python中的heapq

1.堆排序的应用 寻找k个数中的最小值 寻找n个数中的第k大的数 2.高级语言中提供封装好的堆这种结构 2.1 python中: import heapq heapq内置模块位于./Anaconda3/Lib/heapq.py,提供基于堆的优先排序算法. 2.2 什么是堆? 堆的逻辑结构就是完全二叉树,并且二叉树中父节点的值小于等于该节点的所有子节点的值。这种实现可以使用 heap[k] &l...

zhpf225的博客 1424

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

python heapq的用法

经常记不住 做个记录 一、heapq库简介 heapq 库是Python标准库之一,提供了构建小顶堆的方法和一些对小顶堆的基本操作方法(如入堆,出堆等),可以用于实现堆排序算法。 堆是一种基本的数据结构,堆的结构是一棵完全二叉树,并且满足堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点。 堆结构分为大顶堆和小顶堆,在heapq中使用的是小顶堆: 大顶堆:每个节点(叶节点除外)的值都大于等于其子节点的值,根节点的值是所有节点中最大的。 小顶堆:每个节点(叶节点除外)的值都小于等于其

cz的博客 2919

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【Python练习cookbook】heapq高级应用

1.从集合中取出最大或最小N个元素 import heapq nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] print(heapq.nlargest(3, nums)) # 输出 [42, 37, 23] print(heapq.nsmallest(3, nums)) # 输出 [-4, 1, 2] 也支持其他参数支持更为复杂的数据结构 ...

Code_LT的博客 668
上一篇: Leetcode的第2题,持续改进算法到cleancode
下一篇: Python LeetCode 10正则表达式
飞凡可期
博客等级 码龄11年 34粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值