用collections.Counter统计文件后缀名最简路径是:利用pathlib.Path(p).suffix获取真实后缀(如'.tar.gz'),转小写过滤空值,配合rglob()遍历文件,一行生成Counter;需加p.is_file()和p.suffix判空防误统,百万文件宜用生成器表达式防内存溢出。

用 collections.Counter 统计后缀名最简路径
直接上手:不用遍历两次、不手动建字典,Counter 一行就能收口。关键在怎么从路径里干净地提取后缀——别用 str.split('.')[-1],它会把 archive.tar.gz 错判成 gz 而不是 .tar.gz。
正确做法是用 pathlib.Path(file).suffix,它按系统规则识别真实后缀(比如返回 '.tar.gz'),再统一转小写避免 .PY 和 .py 被算作两种。
-
pathlib比os.path更可靠,尤其处理带点的文件名或 Windows 路径时 - 记得过滤掉无后缀文件(
.suffix返回空字符串),否则Counter里会出现一个空键 - 如果想统计多级子目录,传
rglob('*')而不是iterdir()
完整可运行代码示例
下面这段可以直接复制执行,统计当前目录下所有带后缀的文件:
from collections import Counter
from pathlib import Path
folder = Path('.')
suffixes = [p.suffix.lower() for p in folder.rglob('*') if p.is_file() and p.suffix]
counter = Counter(suffixes)
for suffix, count in counter.most_common():
print(f"{suffix}: {count}")
注意三点:
立即学习“Python免费学习笔记(深入)”;
-
p.is_file()必须加,否则目录也会被纳入,而目录没有.suffix -
p.suffix是字符串,可能为空,所以要显式判断and p.suffix -
most_common()默认按数量降序,不传参即可;若只要前 5 名,写most_common(5)
遇到 PermissionError 怎么办
遍历中碰到权限不足的目录(如 /System/Volumes/Data/Library/...)会直接抛 PermissionError,整个程序中断。不能靠 try/except 包裹 rglob,因为它是生成器,错误发生在迭代时。
- 改用
os.walk+ 手动跳过异常目录,但失去pathlib的简洁性 - 更实用的折中:用
pathlib.Path().glob只扫当前层,或限定深度(比如先rglob('*.py')再rglob('*.js')) - 真要全盘扫又不想崩,得自己写递归 +
try/except OSError,Counter放在外面累加
性能和边界情况提醒
百万级文件时,[p.suffix for ...] 会一次性生成大列表,内存吃紧。这时该换成生成器表达式:
counter = Counter(p.suffix.lower() for p in folder.rglob('*')
if p.is_file() and p.suffix)
另外注意:
-
.suffix不等于「扩展名」:README没后缀,.gitignore后缀是''(空),my.tar.gz后缀是'.gz'——pathlib默认只认最后一个点之后的部分;若需完整扩展名(如'.tar.gz'),得用.suffixes并拼接,或换正则 - Windows 下大小写不敏感,但
Counter不知道这事,所以统一转小写是必要步骤
真正麻烦的从来不是计数本身,而是你怎么定义“后缀”。Counter 很快,但取对了才作数。


















