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/10/5 15:22:19 阅读更多 →
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/10/7 22:30:51 阅读更多 →
3分钟完成视频字幕提取:开源工具的极简使用指南

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

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

2026/10/4 22:07:39 阅读更多 →

最新新闻

Ubuntu 20.04上Redis Cluster缓存集群的搭建与优化实践

Ubuntu 20.04上Redis Cluster缓存集群的搭建与优化实践

做电商网站的这几年,Redis一直是我们在性能战场上的主力军。尤其是遇上大促、秒杀这种流量洪峰,数据库如果被直接打穿,那基本就是一场事故。我这次要聊的,是在Ubuntu 20.04上从零搭建并优化一套Redis缓存集群的过程,目…

2026/10/9 6:38:29 阅读更多 →
Java毕设避坑指南:选题、源码改造与答辩全攻略

Java毕设避坑指南:选题、源码改造与答辩全攻略

又是一年毕业季前夕,Java 方向的毕设咨询量开始暴涨。说实话,每年这时候我都能收到大量相似的问题:题目怎么选才不会撞车?网上下的源码能不能直接用?答辩的时候老师会问什么?这篇文章就是把我在过去几年里帮…

2026/10/9 6:38:29 阅读更多 →
溶解氧预测实战:LSTM时间序列模型构建与五大避坑指南

溶解氧预测实战:LSTM时间序列模型构建与五大避坑指南

简介:面向计算机相关专业课程设计与期末大作业的深度学习时序预测项目,完整实现了基于溶解氧数据的多模型预测流程。适合正在做毕业课题、课程设计的学生,也适合初学者通过可直接运行的源码快速上手时间序列建模与模型对比。项目包含数据预处…

2026/10/9 6:38:29 阅读更多 →
Pandas电商订单数据分析全流程:从数据清洗到可视化实战

Pandas电商订单数据分析全流程:从数据清洗到可视化实战

做数据分析这行,pandas基本上是躲不开的。哪怕你用的是Spark、Flink这类分布式框架,底层思路和数据处理的习惯,很多还是从pandas这套来的。最近整理电脑,翻出来一个之前帮朋友做的电商订单分析项目,算是一个比较完整的…

2026/10/9 6:38:29 阅读更多 →
pstack-claude:面向开发者的可观察Claude API命令行探针

pstack-claude:面向开发者的可观察Claude API命令行探针

1. 项目概述:pstack-claude 是什么,它解决的是哪类开发者的真实痛点? pstack-claude 这个名字乍看像一个工具组合词,但拆开来看,“pstack”是 Linux 系统中一个真实存在的诊断命令,用于打印指定进程的调用…

2026/10/9 6:38:29 阅读更多 →
给大模型外挂记忆层:claude-mem跨会话记忆架构与落地详解

给大模型外挂记忆层:claude-mem跨会话记忆架构与落地详解

你有没有遇到过这样的情况:跟Claude聊一个跨了三个星期的项目,它突然忘了你当初拍板的数据库方案;或者今天在对话里改了一个关键参数,明天接着问的时候,它给出的还是改之前的老答案。挺抓狂的,对吧。其实原…

2026/10/9 6:37:29 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →