解决os.walk遍历目录时文件/目录层级索引分配错误问题
Hey there! Let's work through this directory indexing problem you're stuck on—this will save your company's secretary so much manual renaming work once we get it right.
The Core Issue with Your Current Code
Your os.walk approach doesn’t track the parent-child hierarchy of directories. Right now, rootIndex only increments when it hits an empty directory, which is why A-1.1 gets assigned index 2 instead of 1.1—it’s just counting empty directories in traversal order, not the actual nested structure.
Solution: Recursive Traversal for Hierarchical Tracking
Recursion is perfect here because it naturally follows nested directory trees, letting us pass down parent indexes to build the full hierarchical path. Here’s a working implementation that matches your desired output:
import os def assign_hierarchical_indexes(root_path, parent_index="", level=0): # Sort entries to ensure consistent numbering order all_entries = sorted(os.listdir(root_path)) # Split entries into directories and files subdirs = [entry for entry in all_entries if os.path.isdir(os.path.join(root_path, entry))] files = [entry for entry in all_entries if os.path.isfile(os.path.join(root_path, entry))] # Handle directory indexing if level == 0: # Root-level directories get simple numeric indexes (1, 2, 3...) for idx, dir_name in enumerate(subdirs, start=1): current_idx = str(idx) print(f'DIR : {current_idx} - {os.path.join(root_path, dir_name)}') # Recurse into subdirectory, passing current index as parent assign_hierarchical_indexes(os.path.join(root_path, dir_name), current_idx, level + 1) else: # Nested directories get parent-based indexes (parent_idx.1, parent_idx.2...) for idx, dir_name in enumerate(subdirs, start=1): current_idx = f"{parent_index}.{idx}" print(f'DIR : {current_idx} - {os.path.join(root_path, dir_name)}') assign_hierarchical_indexes(os.path.join(root_path, dir_name), current_idx, level + 1) # Handle file indexing file_counter = 1 for file_name in files: if level == 0: file_idx = str(file_counter) else: file_idx = f"{parent_index}.{file_counter}" print(f'file :: {file_idx} - {file_name}') file_counter += 1 # Replace with your actual root directory path rootDir = "/.../root" assign_hierarchical_indexes(rootDir)
How This Works
- Hierarchy Tracking: The function passes the parent directory’s index down to its children, so nested directories get indexes like
1.1,1.2instead of random sequential numbers. - Consistent Order: We sort all entries first to ensure numbering matches your desired structure (no random order surprises).
- Level Distinction: The
levelparameter lets us treat root-level directories differently—they get simple numeric indexes—while nested ones inherit parent indexes.
Extending to Actual Renaming
If you want to automatically rename directories/files (not just print indexes), modify the code with os.rename. Here’s an example for directories:
# Replace the directory print statement with this: new_dir_name = f"{dir_name.split('-')[0]}-{current_idx}" # Adjust to match your naming pattern old_dir_path = os.path.join(root_path, dir_name) new_dir_path = os.path.join(root_path, new_dir_name) os.rename(old_dir_path, new_dir_path) # Important: Recurse into the NEW directory path after renaming assign_hierarchical_indexes(new_dir_path, current_idx, level + 1)
For files:
# Replace the file print statement with this: file_base, file_ext = os.path.splitext(file_name) new_file_name = f"{file_base.split('-')[0]}-{file_idx}{file_ext}" old_file_path = os.path.join(root_path, file_name) new_file_path = os.path.join(root_path, new_file_name) os.rename(old_file_path, new_file_path)
⚠️ Pro Tip: Always back up your directory structure before running renaming code to avoid accidental data loss!
Matching Your Desired Output
Running this code will generate exactly the indexing structure you outlined:
A-1gets index1, its subdirectoryA-1.1gets1.1, files under it get1.1.1,1.1.2, etc.B-2gets index2, with nested indexes following the same pattern.
内容的提问来源于stack exchange,提问作者yoK0

