Python os.walk遍历目录时标注路径所属一级文件夹方法
问题背景
在示例目录结构中,Project根目录下存在das、des、dga三个一级子文件夹,以及根文件randomfile.xlsx,各一级子文件夹内还嵌套有子文件夹与对应文件,目录结构如下:
📦Project ┣ 📂das ┣ 📂des ┃ ┣ 📂subfolder_des1 ┃ ┃ ┗ 📜COM-EL-DES-0002-0.pdf ┃ ┗ 📜COM-EL-DES-0001-0.pdf ┣ 📂dga ┃ ┣ 📂subfolder_dga1 ┃ ┃ ┗ 📜3500-ST-DGA-0047-0.pdf ┃ ┣ 📂subfolder_dga2 ┃ ┃ ┣ 📜3500-ST-DGA-0046-0.pdf ┗ 📜randomfile.xlsx
现有代码通过os.walk遍历Project目录下的全量目录树,将所有文件、文件夹路径收集后存入pandas DataFrame,收集到的路径示例如下:
c:/Project/das c:/Project/des c:/Project/dga c:/Project/des/subfolder_des1/ c:/Project/des//subfolder_des1/COM-EL-DES-0002-0.pdf ... ...
目标要求
需要给收集到的路径新增第二列标注,规则如下:
- 根目录下的文件统一标注为
Project(或root_files) - 所有位于一级文件夹下的子文件夹、文件,无论嵌套深度多少,均标注对应一级文件夹名称,忽略深层子文件夹层级
期望输出的DataFrame格式如下:
Path col2 c:/Project/das das c:/Project/des des c:/Project/dga dga c:/Project/des/subfolder_des1/ des c:/Project/des/subfolder_des1/COM-EL-DES-0002-0.pdf des c:/Project/randomfile.xlsx Project c:/Project/dga/subfolder_dga1/ dga ... ...
注意:示例中的das、des、dga仅为演示用名,脚本需要适配任意输入路径,自动识别一级文件夹名称,不可硬编码目录名。
现有初始代码
目前已写出基础遍历框架,以及未验证的一级目录匹配函数:
import os import pandas as pd from pathlib import Path def dir_tree(path): dir_list = [] col2_list = [] for root, dirs, files in os.walk(path): for d in dirs: dir_list.append(os.path.join(root, d)) for f in files: dir_list.append(os.path.join(root, f)) return dir_list, col2_list def save_to_df(path): dir_list, col2_list = dir_tree(path) dir_tree_df = pd.DataFrame({"Path" : dir_list, "col2" : col2_list}) # 待验证的匹配函数 def get_folder_name(path_str: str, source_directory: str) -> str: path_replace = path_str.replace(source_directory, "") path = Path(path_replace) parts = path.parts joined = os.path.join(source_directory, parts[1]) if os.path.isfile(joined): return "root_files" else: return parts[1]
实现方案
原有get_folder_name的核心思路正确,仅需补全路径标准化、边界场景处理,整合到遍历流程即可直接使用,修改后完整可运行代码如下:
import os import pandas as pd from pathlib import Path def get_top_level_tag(full_path: str, root_path: str) -> str: # 统一路径格式,处理斜杠不一致、多余斜杠问题 full_path = os.path.normpath(full_path) root_path = os.path.normpath(root_path) # 计算相对路径,避免字符串替换的匹配错误 rel_path = os.path.relpath(full_path, root_path) rel_parts = Path(rel_path).parts # 相对路径长度为1说明是根目录下直接的文件/文件夹 if len(rel_parts) == 1: # 是文件则标记为Project,是文件夹则返回自身名称 if os.path.isfile(full_path): return "Project" else: return rel_parts[0] # 相对路径长度大于1,第一部分就是一级文件夹名 else: return rel_parts[0] def dir_tree(root_path): dir_list = [] col2_list = [] # 若不需要把根目录本身加入结果,可注释下面两行 dir_list.append(root_path) col2_list.append("Project") for current_root, dirs, files in os.walk(root_path): for d in dirs: full_d_path = os.path.join(current_root, d) dir_list.append(full_d_path) col2_list.append(get_top_level_tag(full_d_path, root_path)) for f in files: full_f_path = os.path.join(current_root, f) dir_list.append(full_f_path) col2_list.append(get_top_level_tag(full_f_path, root_path)) return dir_list, col2_list def save_to_df(path): dir_list, col2_list = dir_tree(path) dir_tree_df = pd.DataFrame({"Path" : dir_list, "col2" : col2_list}) return dir_tree_df # 调用示例 if __name__ == "__main__": df = save_to_df("c:/Project") print(df)
逻辑说明
- 用
os.path.normpath统一处理不同系统的斜杠格式、多余斜杠问题,避免路径解析错误 - 用
os.path.relpath计算目标路径相对于根目录的相对路径,比直接字符串替换更可靠,不会出现根目录名和子路径重名导致的匹配错误 - 按相对路径的分段长度判断:如果分段长度为1,说明是根目录下直接存放的内容,文件标记为
Project,文件夹返回自身名称;如果分段长度大于1,第一段就是所属的一级文件夹名,直接返回即可 - 遍历过程中直接计算标签,不需要提前存储所有路径再二次处理,执行效率更高
内容的提问来源于stack exchange,提问作者user14380579
相关产品推荐
相关产品推荐

