优先使用 heapq.nlargest/nsmallest 而非 sorted()[:k],因其时间复杂度 o(n log k) 远优于 o(n log n),内存占用更少,尤其适用于大数据量、小 k 值及内存受限场景。

直接用 heapq.nlargest 或 heapq.nsmallest,别手写堆逻辑——它们底层用 C 实现,比纯 Python 循环 + 排序快得多,尤其当 K 远小于数据总量时。
为什么不用 sorted()[:k]?
对百万级列表取 top-10,sorted() 会完整排序所有元素,时间复杂度 O(n log n);而 heapq.nlargest(10, data) 只维护大小为 10 的堆,时间复杂度 O(n log k),实际运行快 3–5 倍。内存也更省:不需要复制整个列表。
常见错误现象:sorted(data, reverse=True)[:10] 在数据量大时卡顿、内存飙升;换成 heapq.nlargest(10, data) 后响应明显变快。
- 适用场景:流式数据、内存受限环境、K
- 注意:如果 K 接近 n(比如取 top-90%),
heapq反而更慢,此时直接sorted()更合适 -
heapq.nlargest支持key参数,和sorted()一致,例如heapq.nlargest(5, users, key=lambda x: x.score)
如何处理可迭代但不支持随机访问的数据源?
比如从文件逐行读、数据库游标、生成器——这些没法用 sorted(),但 heapq.nlargest 能直接消费迭代器,边读边建堆,不缓存全部数据。
示例:从大日志文件中取耗时最长的 3 条请求
with open('access.log') as f:
top3 = heapq.nlargest(3, f, key=lambda line: float(line.split()[-2]))
关键点:
python-docx Skill功能概述python-docx Skill是一项面向实际任务的技能,主要用于本Skill提供使用python-docx生成专业Word文档的标准方法和最佳实践;生成安全服务方案文档;核心要点生成技术架构设计文档;生成任何需要专业排版的Word文档;核心库 : python-docx;使用与执行辅助库 : docx.shared , docx.enum , docx.oxml.ns;标准代码模板;1. 文档初始化;2. 字体设置(必须!它将相关步骤、工具调用和结果整理方式集
- 输入可以是任意可迭代对象,不要先转成 list
- 如果数据源本身是生成器且可能为空,
heapq.nlargest(0, gen)返回空列表,不会报错 - 避免写
list(gen)再传给nlargest,否则失去流式优势
自定义比较逻辑时,别改原始数据结构
Python 堆只支持最小堆,nlargest 内部已自动处理逆序逻辑。若需复杂排序(如按多个字段、优先级组合),别试图重载 __lt__ 或包装对象——容易出错且影响性能。
正确做法:用 key 函数返回元组,让自然排序生效
# 按 score 降序,score 相同时按 name 升序 heapq.nlargest(5, players, key=lambda p: (p.score, -ord(p.name[0])))
或者更稳妥地:
heapq.nlargest(5, players, key=lambda p: (p.score, p.name))
因为 heapq.nlargest 对元组按字典序比较,且默认对第二字段升序;若需第二字段也降序,就用负数或 str 取反技巧(如 -p.age 或 p.name[::-1])。
- 切忌在
key中做耗时计算(如网络请求、文件读取),它会被调用 n 次 - 如果 key 计算复杂,先用生成器预计算
(key_val, item)对,再传给nlargest - 不要用
heapq.heappush手动维护堆来模拟 top-k——除非你明确需要在线插入/删除,否则纯属增加 bug 风险
真正要注意的是 key 函数的稳定性:如果两个元素 key 值完全相同,nlargest 返回的相对顺序和原始迭代顺序一致,但不保证跨 Python 版本或不同输入规模下完全一致——别依赖这个行为做业务逻辑判断。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










