Python 用 heapq 实战:Top-K、优先队列与合并多个有序流
Python 用 heapq 实战:Top-K、优先队列与合并多个有序流有个很常见的需求:从一百万条日志里找出耗时最长的 10 条。很多人第一反应是sorted(data, reverseTrue)[:10]——排完序取前 10。能跑,但你为了 10 条结果把一百万条全排了一遍,O(n log n)的功全花在你根本不要的那 99.9% 数据上。这类「从大堆里挑最大/最小的几个」问题,正确工具是堆(heap)。Python 标准库的heapq就是一个基于列表的最小堆实现,不用装任何东西。这篇把它三个最实用的场景讲透。先认识 heapq:它是「最小堆」heapq直接操作普通 list,把它当堆用。核心两个操作:heappush压入、heappop弹出最小值。importheapq h[]heapq.heappush(h,5)heapq.heappush(h,1)heapq.heappush(h,3)print(heapq.heappop(h))# 1,永远先弹最小的print(heapq.heappop(h))# 3记住一句话:堆顶(h[0])永远是当前最小值,heappop弹的也是它。这是后面所有技巧的基础。场景一:Top-K 最大值,别全排序要找最大的 K 个,直觉是「用最大堆」,但更省内存的做法是维护一个大小为 K 的最小堆:遍历数据,堆没满就压;满了就拿新值跟堆顶(当前 K 个里最小的)比,比它大就替换掉堆顶。importheapqdeftop_k(nums,k):h[]forxinnums:iflen(h)k:heapq.heappush(h,x)elifxh[0]:# 比 K 个里最小的还大,才值得进来heapq.heapreplace(h,x)# 弹最小 压新值,一步完成比 poppush 快returnsorted(h,reverseTrue)print(top_k([3,1,9,7,2,8,5],3))# [9, 8, 7]复杂度O(n log k),内存只占 K 个元素。数据是流式来的(读不完的日志、网络包)时,这个「只留 K 个」的特性尤其关键——你没法先攒齐再排序。标准库其实封装好了这个模式:heapq.nlargest(k, nums)和nsmallest(k, nums),内部就是上面的逻辑,还支持key:logs[{url:/a,ms:120},{url:/b,ms:998},{url:/c,ms:45}]slowestheapq.nlargest(2,logs,keylambdar:r[ms])一个选型提醒:K 很小(比如 top 10)用nlargest;但如果 K 接近 n(比如取前 90%),直接sorted反而更快,别硬套堆。场景二:优先队列,用元组带 priority任务调度里经常要「优先级高的先执行」。堆本身只会按元素大小排,想按优先级排,就把(priority, task)打包成元组压进去——元组比较是逐位比的,先比第一个元素。importheapq pq[]heapq.heappush(pq,(2,发邮件))heapq.heappush(pq,(1,付款))# 数字小 优先级高heapq.heappush(pq,(3,归档))whilepq:prio,taskheapq.heappop(pq)print(prio,task)# 1 付款 → 2 发邮件 → 3 归档这里有个真实会炸的坑:如果两个任务 priority 相同,元组会去比第二个元素task。task 要是个不可比较的对象(比如自定义类实例),直接TypeError: not supported。解决办法是插入一个自增序号做「平局裁判」,保证元组永远能比出大小,顺便实现了同优先级下的 FIFO:importheapq,itertools counteritertools.count()# 全局自增计数器pq[]defpush(pq,priority,task):# (优先级, 序号, 任务):序号唯一,元组比较永远不会落到 task 上heapq.heappush(pq,(priority,next(counter),task))push(pq,1,object())# 不可比较的对象也没问题push(pq,1,object())# 同优先级,按入队顺序出场景三:合并 K 个有序流,不爆内存假设你有 10 个已经按时间排好序的日志文件,要合成一条全局有序的流。全读进内存再sorted是最蠢的做法——文件可能几个 G。heapq.merge专为此而生,它接收多个有序可迭代对象,惰性地产出一个全局有序的迭代器:importheapq a[1,4,7]b[2,5,8]c[3,6,9]forxinheapq.merge(a,b,c):print(x,end )# 1 2 3 4 5 6 7 8 9关键在「惰性」:merge任意时刻只在堆里放 K 个元素(每个流的当前头),内存占用跟流的数量有关,跟总数据量无关。配合生成器读文件,几个 G 的日志归并也只占几 KB 内存:defread_sorted(path):withopen(path)asf:forlineinf:# 逐行 yield,不一次性读入yieldline.rstrip()mergedheapq.merge(read_sorted(log1),read_sorted(log2),keylambdas:s[:19])小结heapq是标准库的最小堆,直接操作 list,堆顶h[0]永远是最小值。Top-K用大小为 K 的最小堆(或直接nlargest/nsmallest),O(n log k),省内存、能处理流式数据。优先队列用(priority, 序号, task)元组,加自增序号避免同优先级时比较到不可比对象。合并有序流用heapq.merge,惰性归并,内存只跟流数量相关。一句话记忆:要「全局有序」用 sort,要「局部最值/前几名/惰性归并」用 heap。分不清就问自己——我是不是根本不需要剩下那些数据的顺序?

相关新闻

LLMOps 这词,我一个做运维的琢磨了两个月

LLMOps 这词,我一个做运维的琢磨了两个月

我们团队去年接了个新摊子:把公司内部的几个对话模型对外提供服务。领导在会上提了一嘴"这叫 LLMOps",我当时心里咯噔一下——又来新词,是不是又要我加班学一套没听说过的东西?会后我还偷偷搜了下,出来的文章…

2026/11/1 7:55:27 阅读更多 →
ExifToolGUI终极指南:三分钟掌握专业级元数据批量编辑

ExifToolGUI终极指南:三分钟掌握专业级元数据批量编辑

ExifToolGUI终极指南:三分钟掌握专业级元数据批量编辑 【免费下载链接】ExifToolGui A GUI for ExifTool 项目地址: https://gitcode.com/gh_mirrors/ex/ExifToolGui 还在为海量照片的元数据管理而烦恼吗?ExifToolGUI这个免费工具能让您在几分钟内…

2026/11/1 21:02:01 阅读更多 →
英雄联盟智能助手Seraphine:让数据成为你的最强队友

英雄联盟智能助手Seraphine:让数据成为你的最强队友

英雄联盟智能助手Seraphine:让数据成为你的最强队友 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine Seraphine是一款基于英雄联盟官方LCU API开发的智能助手工具,能够自动查询队友和对…

2026/11/1 21:02:05 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/1 0:24:43 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/1 10:36:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/1 10:36:51 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/1 1:06:58 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/1 10:35:11 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/1 9:35:41 阅读更多 →

日新闻

周新闻

月新闻