【Python Cookbook】S01E03 找到最大最小的N个元素

目录

  • 问题
  • 解决方案
  • 讨论

问题

如何在一个集合中找到最大或最小的 N 个元素?

解决方案

使用 heapq 模块。

pip install heapq

heapq 模块中,有 nlargest() 以及 nsmallest() 两个函数:

import heapqnums = [1, 8, 23, 2, 7, -4, 8, 18, 42, 37]
print(heapq.nlargest(3, nums))
print(heapq.nsmallest(3, nums))

在这里插入图片描述

# nlargest函数结构
nlargest(n, arr, key)		# 其中n为取出的数量,arr为数组
# nsmallest函数结构
nsmallest(n, arr, key)

而由于这两个函数 nlargest() nsmallest 都接受一个参数 key,有了这个参数,就可以允许它们工作在更加复杂的数据结构之中。

import heapqprofolio = [{"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":"ACME", "shares": 75, "price": 115.65}
]cheap = heapq.nsmallest(3, profolio, key=lambda s:s['price'])
print(cheap)

在这里插入图片描述

讨论

如果寻找集合 A A A 中最大最小的 N N N 个元素,且 N < < l e n ( A ) N<<len(A) N<<len(A),那么使用下述方案可以提供更好的性能。

首先函数会在底层将集合转化为列表,元素会以堆的顺序排列。

import heapqnums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
heap = list(nums)
heapq.heapify(heap)
print(heap)

上述代码 print(heap) 的结果为:

[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]

在堆数据结构中,父节点和子节点的关系是基于数组的索引来确定的。对于一个给定的节点,其索引为 i i i,它的父节点、左子节点和右子节点的索引可以通过特定的公式计算得出。

而在 Pythonheapq 模块实现的最小堆中,堆是一个列表,且堆属性满足对于所有索引 i i i(除了根节点,其索引为0),都有 h e a p [ i ] > = h e a p [ ( i − 1 ) / / 2 ] heap[i] >= heap[(i-1)//2] heap[i]>=heap[(i1)//2]

即任何父节点的值都小于或等于其子节点的值。

[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]

在这个堆中,

  • 索引 0 的元素是 -4,它是根节点,没有父节点。
  • 索引 1 的元素是 2,它的父节点是 -4(索引为 (1-1)//2 = 0)。
  • 索引 2 的元素是 1,它的父节点也是 -4(索引为 (2-1)//2 = 0)。
  • 索引 3 的元素是 23,它的父节点是 2(索引为 (3-1)//2 = 1)。
  • 索引 4 的元素是 7,它的父节点是 2(索引为 (4-1)//2 = 1)。
  • 索引 5 的元素是 2,它的父节点是 1(索引为 (5-1)//2 = 2)。
  • 以此类推,可以找到每个节点的父节点。

同样地,可以找到每个节点的子节点:

  • 索引 0 的 -4 的左子节点是 2(索引为 2*0 + 1 = 1),右子节点是 1(索引为 2*0 + 2 = 2)。
  • 索引 1 的 2 的左子节点是 23(索引为 2*1 + 1 = 3),右子节点是 7(索引为 2*1 + 2 = 4)。
  • 索引 2 的 1 的左子节点是 2(索引为 2*2 + 1 = 5),但没有右子节点(因为索引 2*2 + 2 = 6 处没有元素)。
  • 以此类推,可以找到每个节点的子节点。

Pythonheapq 模块提供了一个 heapify 函数,该函数能够将一个可变的列表转换为最小堆。过程是自动的,但是可以进行模拟:

  1. 首先找到最后一个非叶子节点的索引:
    • 在一个完全二叉树中,最后一个非叶子节点的索引是 len(heap) // 2 - 1
    • 而本列表中, len(nums) = 11,所以最后一个非叶子节点的索引是 11 // 2 - 1 = 4
  2. 从最后一个非叶子节点开始,向上进行堆化(heapify):
    • 对于每个节点,比较它与它的子节点的值。
    • 如果节点的值大于其子节点中的最小值,则交换这个节点与其最小子节点的值。
    • 重复这个过程,直到堆的根节点。
  3. 重复步骤2,直到整个列表满足堆属性。

手动模拟过程:

# 初始列表
heap = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]# 从最后一个非叶子节点开始,向上进行堆化
last_non_leaf = len(heap) // 2 - 1
for i in range(last_non_leaf, -1, -1):# 比较当前节点与其子节点的值,并进行交换current = heap[i]left_child_idx = 2 * i + 1right_child_idx = 2 * i + 2smallest = i# 如果左子节点存在且小于当前节点,更新最小值索引if left_child_idx < len(heap) and heap[left_child_idx] < current:smallest = left_child_idx# 如果右子节点存在且小于最小值,更新最小值索引if right_child_idx < len(heap) and heap[right_child_idx] < heap[smallest]:smallest = right_child_idx# 如果当前节点不是最小值,交换它们if smallest != i:heap[i], heap[smallest] = heap[smallest], heap[i]# 最终的堆
print(heap)

执行上述代码后,我们得到了一个最小堆。这个过程是迭代的,从最后一个非叶子节点开始,向上逐步将每个节点与其子节点进行比较和交换,直到整个列表满足堆属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/844380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小阿轩yx-Shell编程之正则表达式与文本处理器

小阿轩yx-Shell编程之正则表达式与文本处理器 正则表达式 &#xff08;RegularExpression&#xff0c;RE&#xff09; 正则表达式概述 正则表达式的定义 又称 正规表达式常规表达式 代码中常简写为 regex、regexp 或 RE 正则表达式 使用单个字符串来描述、匹配一系列符…

C++笔试强训day36

目录 1.提取不重复的整数 2.【模板】哈夫曼编码 3.abb 1.提取不重复的整数 链接https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1?tpId37&tqId21232&ru/exam/oj 按照题意模拟就行&#xff0c;记得从右往左遍历 #include <iostream> usi…

GPT-4O神器来袭!自动生成Figma设计稿,移动端开发瞬间加速!

2024年5月29日- 近日&#xff0c;一款基于GPT-4O技术的创新工具成功实现根据产品需求文档&#xff08;PRD&#xff09;自动生成Figma设计稿的功能&#xff0c;为移动端应用开发者带来革命性的便捷。据悉&#xff0c;该功能主要针对移动端应用进行优化&#xff0c;并支持使用高质…

【环境配置】windows的磁盘分区、VMware下的ubuntu20的安装、虚拟机系统界面过小的处理

这段时间在折腾自己的笔记本&#xff0c;刚好也有同学新买台式机咨询安装VMware软件&#xff0c;就顺便记录下windows的环境的一些操作。方便自己需要时查阅。 1 windows磁盘分区 在Windows系统中&#xff0c;磁盘分区和管理可以通过【磁盘管理】工具进行。要打开磁盘管理&…

系统架构设计师【第2章】: 计算机系统基础知识 (核心总结)

文章目录 2.1 计算机系统概述2.2 计算机硬件2.2.1 计算机硬件组成2.2.2 处理器2.2.3 存储器2.2.4 总线2.2.5 接口2.2.6 外部设备 2.3 计算机软件2.3.1 计算机软件概述2.3.2 操作系统2.3.3 数据库2.3.4 文件系统2.3.5 网络协议2.3.6 中间件2.3.7 软件构件2.3.8 …

安卓开发板_开发评估套件_4G/5G联发科MTK安卓主板定制开发

安卓开发板采用了联发科八核A53 CPU&#xff0c;主频2.0GHz&#xff0c;采用12nm制程工艺&#xff0c;拥有强大的通用计算性能。配备GE8300 GPU&#xff0c;支持1080P视频编码和H.264硬解码&#xff0c;能够解析目前流行的视频和图片格式&#xff0c;非常适合各种功能APP的测试…

网络工程基础 不同网段下的设备实现通信

交换机可以实现同一个网段下的不同设备直接通信 路由器可以实现不同的网段下的设备进行通信 路由器查看路由表命令 display ip routing-table 华为路由器配置静态路由命令&#xff1a; ip route-static 目的网络地址 子网掩码 下一跳地址 电脑判断不同网段的ip会把请求转给网…

SOL 交易机器人基本知识

有没有可以盈利的机器人&#xff1f; 是的&#xff0c;各行各业都有许多盈利机器人。在金融领域&#xff0c;交易机器人被广泛用于自动化投资策略并根据预定义的算法执行交易。这些机器人可以分析市场趋势并做出快速决策&#xff0c;从而可能带来可观的回报。同样&#xff0c;在…

CentOS下安装SVN客户端及使用方法

一、前言 Subversion&#xff08;SVN&#xff09;是一款开源的版本控制系统&#xff0c;它可以帮助开发者追踪和管理代码、文档或其他文件的更改历史。在Linux系统中&#xff0c;特别是在CentOS环境下&#xff0c;安装和使用SVN客户端是日常工作中常见的任务。本文将介绍如何在…

【PHP项目实战训练】——laravel框架的实战项目中mysql数据库的数据的数据在blade.php中展示

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【Python Cookbook】S01E02 从任意长度的可迭代对象中分解元素

目录 问题解决方案讨论 问题 从某个不确定长度的迭代对象中分解出 N N N 个元素。 解决方案 *分解操作和各种函数式语言中的列表处理功能有着一定的相似性。例如&#xff0c;如果有一个列表&#xff0c;可以像下面这样轻松将其分解为头部和尾部。 scores [99, 97, 91, 89…

【Java】HOT100+代码随想录:动态规划(下)

目录 三、打家劫舍 LeetCode198&#xff1a;打家劫舍 LeetCode213&#xff1a;打家劫舍ii LeetCode337&#xff1a;打家劫舍iii&#xff08;树形&#xff09; 四、股票问题 时间不多了&#xff0c;其他的先不写了 LeetCode121&#xff1a;买卖股票的最佳时机 五、子序列…

Plesk面板上网站无法访问如何查看日志

近期我的网站出现无法访问的问题&#xff0c;这边想要查询为什么出现无法访问的原因&#xff0c;但不知道如何在主机上面进行检查&#xff0c;由于我使用的Hostease的Windows虚拟主机产品默认带普通用户权限的Plesk面板&#xff0c;因此联系Hostease的咨询了Hostease技术支持&a…

建立FTP服务器

文章目录 建立FTP服务器1. 使用VMware安装CentOS 7虚拟机。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&#xff08;onboot改为yes&#xff09;并重启网络服务&#xff0c;查看相应IP地址&#xff0c;并使用远程连接软件进行连接。3.配置yum源&#xff0…

能芯(EnChip)模拟芯片应用和选型

数据显示&#xff0c;超过60%的驾驶者会在开车时听音乐&#xff0c;这不仅可以提高驾驶者的注意力&#xff0c;还可以缓解驾驶过程中产生的疲劳和压力&#xff0c;特别是在长途驾驶或交通拥堵时尤其明显。基于音乐欣赏&#xff0c;高保真音质是音响系统的核心指标之一&#xff…

高考前很焦虑?看看罗永浩提的三个建议!罗永浩推荐的随身WiFi居然蕴含这样的商机?2024普通人如何翻身?

你能相信现如今身家过亿的老罗罗永浩高中就辍学了吗&#xff1f;相信很多人都不敢置信吧。罗永浩无论是表现出来的口才、情商还是智商&#xff0c;无论如何都无法让人把他和高中辍学联系起来。 而这一点似乎也是老罗人生中的一个遗憾&#xff0c;于是又在一年高考季的时候&…

相对位姿估计

相对位姿估计 示意图 理论推导 离线数据库&#xff1a; P的位置 P [ X , Y , Z ] T P[X,Y,Z]^{T} P[X,Y,Z]T 相机内参 k 1 k_{1} k1​ 安卓手机&#xff1a; 相机内参 k 2 k_{2} k2​ 两个像素点位置 &#xff1a; p 1 和 p 2 p_1和p_2 p1​和p2​ 公式一&#xff1a;…

为师妹写的《Java并发编程之线程池十八问》被表扬啦!

写在开头 之前给一个大四正在找工作的学妹发了自己总结的关于Java并发中线程池的面试题集,总共18题,将之取名为《Java并发编程之线程池十八问》,今天聊天时受了学妹的夸赞,心里很开心,毕竟自己整理的东西对别人起到了一点帮助,记录一下! Java并发编程之线程池十八问 经过…

5月岚庭工人大会“安全就是效率、形象即是品质”

2024年5月18日、19日岚庭一月一期的“产业工人大会”和“工程大会”圆满举行初夏正当时&#xff0c;此次大会主要围绕“安全”与“形象”展开六场专题培训只为精益求精产业工人和装修管家全体到场。 岚庭 以绝对【安全】护家护园 安全就是生命&#xff0c;违章就是事故&#x…

开源DMS文档管理系统 Nuxeo Vs Alfresco对比及 API 使用概述

1. 文档管理系统是什么 文档管理系统&#xff08;DMS&#xff1a;Document Management System&#xff09;是一种软件系统&#xff0c;用于组织、存储、检索和管理电子文档和文件。这些文件可以是各种格式的电子文档&#xff0c;如文本文档、电子表格、图像、音频或视频文件等…