Python 的 collections:别再用字典手写计数和分组

举报
yd_268445051 发表于 2026/11/10 10:10:37 2026/11/10
【摘要】 Python 的 collections:别再用字典手写计数和分组统计词频、按类别分组,是写 Python 时最常遇到的两件事。顺手写法是先建一个空字典,再写一圈 if key in d 判断:counts = {}for word in words: if word in counts: counts[word] += 1 else: counts...

Python 的 collections:别再用字典手写计数和分组

统计词频、按类别分组,是写 Python 时最常遇到的两件事。顺手写法是先建一个空字典,再写一圈 if key in d 判断:

counts = {}
for word in words:
    if word in counts:
        counts[word] += 1
    else:
        counts[word] = 1

五六行代码只干了一件事——计数,而且每个要计数的脚本都得重写一遍。字典本身没错,错的是把“缺 key 时怎么办”这件事一次次交给手写判断。collections 里的现成类型,就是为这类重复劳动准备的。

第一个是 Counter,专做计数。上面那段循环可以缩成一行:

from collections import Counter

counts = Counter(words)
print(counts.most_common(3))  # 出现最多的 3 个

Counter 本质还是字典,counts[word] 照常用;没出现过的 key 读出来是 0 而不是抛 KeyError,所以 counts[word] += 1 不用先判断存在。两个 Counter 还能直接相加、相减,合并两份统计结果不用再写循环。想取 Top N,most_common(n) 一步到位,比先排序再切片省事,也少一次写错排序方向的机会。

第二个是 defaultdict,专做分组。按首字母把单词分组,手写字典要先判断 key 在不在:

from collections import defaultdict

groups = defaultdict(list)
for word in words:
    groups[word[0]].append(word)

defaultdict(list) 的意思是:访问不存在的 key 时,自动先放一个空列表进去。于是 groups["a"].append(word) 不管 "a" 出现没出现过都能直接写,判断逻辑被收进了类型本身。分组的值也可以是 set 去重、是 int 做累加,工厂函数换一个,整段分组代码不用改结构。记住一点:defaultdict 只在访问时自动建 key,in 判断和 .get() 不会触发它,读之前先想清楚要不要新建。

第三个顺手的是 deque,专做两端操作。列表在尾部追加很快,但在头部插入或弹出要把后面所有元素挪一位,数据量一大就慢下来:

from collections import deque

recent = deque(maxlen=5)
for event in events:
    recent.append(event)   # 超出 5 条自动丢掉最旧的

deque 两端追加和弹出都是 O(1),appendleft、popleft 随手可用;maxlen 还能顺手做一个固定长度的“最近 N 条”窗口,满了自动丢最旧的,不用自己维护下标。需要随机按下标访问、频繁切片时还是用列表,deque 的长处在两端,不在中间。

最后记住分工:计数找 Counter,分组找 defaultdict,两端进出找 deque。它们都不是新语法,只是把“缺 key 怎么办”“头部操作慢怎么办”这类重复判断收进标准库。字典继续用在它最擅长的地方——明确的 key 到 value 映射;一发现自己又在写 if key in d,就停下来想一想,collections 里是不是已经有人替你写好了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。