Python collections 实战:defaultdict、Counter、deque 解决三类高频痛点
Python collections 实战:defaultdict、Counter、deque 解决三类高频痛点你写 Python 处理数据时,大概率反复写过这三段代码:判断 key 在不在字典里再初始化、手动累加计数、用list.pop(0)从头部删元素。它们能跑,但要么啰嗦要么慢。标准库collections里有三个容器专治这三种痛点。这篇用真实场景对比「朴素写法」和「正确写法」,让你以后条件反射就用对。痛点一:分组时反复判断 key 存在——用 defaultdict把一批订单按用户分组,朴素写法:orders[(alice,100),(bob,50),(alice,30),(bob,20),(alice,10),]grouped{}foruser,amountinorders:ifusernotingrouped:# 每次都要判断初始化grouped[user][]grouped[user].append(amount)# {alice: [100, 30, 10], bob: [50, 20]}那句if user not in grouped出现在每一个分组循环里,重复又容易忘。defaultdict让「key 不存在时自动初始化」变成默认行为:fromcollectionsimportdefaultdict groupeddefaultdict(list)# 访问不存在的 key 时,自动 list()foruser,amountinorders:grouped[user].append(amount)# 直接 append,不用判断defaultdict(list)里的list是一个工厂函数:每当访问一个不存在的 key,它就调用list()生成空列表作为默认值。换成int就能做累加计数:countsdefaultdict(int)# 默认值 0foruser,_inorders:counts[user]1# 不存在时先当 0 再 1# {alice: 3, bob: 2}一个坑:defaultdict的「自动创建」发生在读取时。d[k]只要访问就会创建 key,哪怕你只是想检查:ddefaultdict(list)ifd[missing]:# 这一句就凭空创建了 d[missing] []passprint(dict(d))# {missing: []} ← 意外多了一个 key想检查而不创建,用k in d或d.get(k),别用d[k]。痛点二:计数与找 Top N——用 Counter统计词频,朴素写法要么手动defaultdict(int),要么更原始。Counter一步到位:fromcollectionsimportCounter wordsapple banana apple cherry banana apple.split()cCounter(words)# Counter({apple: 3, banana: 2, cherry: 1})它的杀手锏是most_common(n),直接按出现次数排序拿 Top N,省掉手写sorted(..., key...):c.most_common(2)# [(apple, 3), (banana, 2)]Counter还支持算术运算,做「两批数据的差异」特别顺手:beforeCounter(a3,b1,c2)afterCounter(a5,b1,d1)after-before# Counter({a: 2, d: 1}) 只保留正数增量afterbefore# 合并累加(afterbefore)# 交集取较小值:Counter({a: 3, b: 1})注意-运算会丢弃结果为 0 或负数的项(c从 2 变 0 直接消失)。想保留负数用c.subtract():dCounter(a1)d.subtract(Counter(a3))# d 变成 Counter({a: -2}),负数保留痛点三:从头部频繁增删——用 deque实现一个「最近 N 条」的滑动窗口,或者 BFS 队列,朴素写法用 list:queue[]queue.append(x)# 尾部加,O(1),没问题queue.pop(0)# 头部删,O(n)!每次都要把后面所有元素前移list.pop(0)是O(n)的——列表底层是连续数组,删头部要把后面全部元素往前挪一格。数据一大,性能就崩。deque(双端队列)两头增删都是O(1):fromcollectionsimportdeque queuedeque()queue.append(1)# 右侧入队 O(1)queue.append(2)queue.popleft()# 左侧出队 O(1),取代 list.pop(0)# → 1deque最实用的一个特性是maxlen,自动实现定长滑动窗口:满了之后,一端进、另一端自动挤出去:recentdeque(maxlen3)# 只保留最近 3 条foriinrange(5):recent.append(i)# deque([2, 3, 4], maxlen3) ← 0 和 1 被自动挤掉了用它做「最近访问记录」「移动平均窗口」再合适不过,完全不用手动判断长度再删头。一个性能直觉对比(10 万次头部出队):importtimefromcollectionsimportdeque N100_000lstlist(range(N))ttime.perf_counter()whilelst:lst.pop(0)# O(n) 每次print(list:,time.perf_counter()-t)# 秒级dqdeque(range(N))ttime.perf_counter()whiledq:dq.popleft()# O(1) 每次print(deque:,time.perf_counter()-t)# 毫秒级差距是数量级的。小结defaultdict(factory):分组、累加时告别if key not in d;但注意d[k]读取即创建,检查用in或.get()。Counter:计数一步到位,most_common(n)拿 Top N,还能用 - 做集合算术求差异(-会丢弃非正数项)。deque:两端增删 O(1),取代慢成 O(n) 的list.pop(0);maxlen自动做定长滑动窗口。一句话记忆点:分组用 defaultdict、计数用 Counter、队列用 deque——看到pop(0)就该警觉换 deque。

相关新闻

终极指南:如何在电脑上免费畅玩Switch游戏的完整教程

终极指南:如何在电脑上免费畅玩Switch游戏的完整教程

终极指南:如何在电脑上免费畅玩Switch游戏的完整教程 【免费下载链接】yuzu 任天堂 Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/yu/yuzu 你是否曾梦想在电脑上体验任天堂Switch的精彩游戏世界?yuzu模拟器正是实现这一梦想的完…

2026/11/4 1:38:30 阅读更多 →
Go 程序在 K8s 里 CPU 被打满:GOMAXPROCS 没感知容器 limits 与 automaxprocs 修复

Go 程序在 K8s 里 CPU 被打满:GOMAXPROCS 没感知容器 limits 与 automaxprocs 修复

Go 程序在 K8s 里 CPU 被打满:GOMAXPROCS 没感知容器 limits 与 automaxprocs 修复 你的 Go 服务在物理机上跑得好好的,一上 Kubernetes,同样的负载 CPU 却莫名被限流(throttling),P99 延迟飙高,GC 也变频繁。查了半天代码没问题,问题出在一个你从没设过的运行时参数:GOMAXPROC…

2026/11/10 3:46:14 阅读更多 →
3分钟完成视频字幕提取:开源工具的极简使用指南

3分钟完成视频字幕提取:开源工具的极简使用指南

3分钟完成视频字幕提取:开源工具的极简使用指南 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测、字幕内容提取。…

2026/11/9 8:52:26 阅读更多 →

最新新闻

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

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

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

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

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

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

2026/11/9 14:56:39 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

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

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

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

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

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

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

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

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

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

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

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

2026/11/9 14:01:11 阅读更多 →

日新闻

周新闻

月新闻