如何用Python Pathlib递归遍历目录按层级统计文件扩展名频次
按目录分层统计文件扩展名实现方案
核心逻辑不需要大改,你之前想到的path.parent是完全正确的方向,只需要调整遍历阶段的收集逻辑,不要只存文件后缀,而是把所属目录、文件后缀、文件完整路径三个信息同时记录,后续统计、按目录处理文件都可以复用这份遍历结果,不需要重复扫盘。
提前规避两个易踩的坑
- 扩展名统一转小写:你给出的目录结构里Project3下是
Info.txt(大写T后缀),如果不做小写转换,会被统计成.txt和.TXT两个独立扩展名,导致结果不准 - 根目录标识处理:根目录下的文件用
parent.relative_to取相对路径会返回.,直接替换成可读性更好的「根目录」标识即可
可直接运行的代码
from pathlib import Path from collections import Counter import pandas as pd dir_to_scan = Path("/Python-Pathlib-Scan-Directory") # 遍历一次存全所有需要的信息,后续统计、文件拼接都复用这份列表 file_records = [] for file_path in dir_to_scan.rglob("*"): if not file_path.is_file(): continue # 计算相对扫描根目录的父路径 parent_rel_path = file_path.parent.relative_to(dir_to_scan) dir_label = "根目录" if str(parent_rel_path) == "." else str(parent_rel_path) # 扩展名统一转小写 file_ext = file_path.suffix.lower() # 记录元组:(目录标识, 扩展名, 文件完整路径) file_records.append( (dir_label, file_ext, file_path) ) # 按(目录, 扩展名)维度统计数量 ext_count = Counter( (rec[0], rec[1]) for rec in file_records ) # 转换为DataFrame stat_df = pd.DataFrame( [ (dir_name, ext, count) for (dir_name, ext), count in ext_count.items() ], columns=["所属目录", "扩展名", "文件数"] ).sort_values(by=["所属目录", "文件数"], ascending=[True, False]).reset_index(drop=True)
运行后输出的统计结果结构如下:
| 所属目录 | 扩展名 | 文件数 |
|---|---|---|
| 根目录 | .csv | 4 |
| 根目录 | .ipynb | 3 |
| 根目录 | .py | 1 |
| Project1 | .xlsx | 2 |
| Project1 | .csv | 1 |
| Project1 | .txt | 1 |
| Project2 | .csv | 1 |
| Project2 | .xlsx | 1 |
| Project2 | .docx | 1 |
| Project3 | .txt | 1 |
适配后续按目录拼接文件的场景
因为第一次遍历已经把所有文件的完整Path对象存在file_records里了,后续要做指定目录的文件拼接不需要再次遍历目录,直接筛选对应记录即可,示例:
# 示例:拼接Project1目录下所有csv文件 target_dir = "Project1" target_ext = ".csv" target_files = [ rec[2] for rec in file_records if rec[0] == target_dir and rec[1] == target_ext ] # 拼接成一个DataFrame combined_csv = pd.concat( [pd.read_csv(f) for f in target_files], ignore_index=True )
可选调整项
- 如果需要展示目录绝对路径,把
dir_label的赋值逻辑换成str(file_path.parent.resolve())即可 - 如果存在多层嵌套子目录,不需要修改代码,rglob会自动递归,
dir_label会自动生成类似Project1/sub_folder的层级标识 - 如果只需要统计特定类型文件,在遍历阶段加扩展名过滤条件即可,能减少不必要的记录存储
内容的提问来源于stack exchange,提问作者Eoin Vaughan
相关产品推荐
相关产品推荐

