如何调整os.walk遍历逻辑实现子文件夹及图片按数值顺序排序
目录遍历数值排序的调整方案
问题本质
两处排序异常均为默认字符串字典序不符合数值排序要求导致:
os.walk遍历子目录的顺序完全依赖subs列表的原有顺序,默认字符串排序会将temp-vts10排在temp-vts2之前(逐字符对比时,temp-vts1的后续字符'1' < '2',因此temp-vts10整体小于temp-vts2)。- 文件默认排序时,
temp-vts1-10.png的-后首字符为'1',小于temp-vts1-2.png的首字符'2',因此出现数字更大的文件排在前面的异常。
调整思路
核心是给两个排序环节指定提取了数字的自定义排序键,同时利用os.walk的特性控制子目录遍历顺序:
- 子目录排序:在每次遍历到当前目录时,原地修改
subs列表(os.walk会直接使用修改后的顺序遍历后续子目录),按提取的子文件夹编号X的数值升序排列。 - 文件排序:给
sorted()方法指定排序键,提前过滤非PNG文件后,按提取的图片序号Y的数值升序排列。
代码实现
适配固定命名规则的简化版
因题目中文件夹、文件的命名规则完全固定(temp-vtsX、temp-vtsX-Y.png),可直接通过字符串切割提取数字,无需引入额外依赖:
import os paths_frames = [] for folder, subs, files in os.walk(path_data): # 原地排序子文件夹:提取temp-vts后的X编号转整数升序 subs.sort(key=lambda s: int(s.split('-')[-1])) # 排序文件:先过滤所有PNG格式文件,再提取Y编号转整数升序 sorted_files = sorted( [f for f in files if f.lower().endswith('.png')], key=lambda f: int(f.split('-')[-1].split('.')[0]) ) for filename in sorted_files: paths_frames.append(os.path.abspath(os.path.join(folder, filename)))
兼容非标准命名的通用版
如果后续可能出现命名不规范的子目录或文件,可通过正则提取数字,避免因命名异常导致报错:
import os import re # 匹配字符串中任意连续数字的正则 digit_pattern = re.compile(r'(\d+)') paths_frames = [] for folder, subs, files in os.walk(path_data): # 原地排序子文件夹:无有效数字的非目标目录排到最后 subs.sort( key=lambda s: int(digit_pattern.search(s).group(1)) if digit_pattern.search(s) else float('inf') ) # 排序文件:过滤PNG格式后按提取的数字升序排列 sorted_files = sorted( [f for f in files if f.lower().endswith('.png')], key=lambda f: int(digit_pattern.search(f).group(1)) ) for filename in sorted_files: paths_frames.append(os.path.abspath(os.path.join(folder, filename)))
关键细节说明
- 必须原地修改
subs列表:os.walk作为生成器,只会读取当前目录下subs列表的顺序决定后续子目录的遍历优先级,直接对subs做原地排序即可控制遍历顺序,无需额外写递归遍历逻辑。 - 替换原有的后缀判断逻辑:原代码用
filename[-3:].lower() == 'png'判断后缀,既可能在文件名长度小于3时触发索引错误,也无法兼容带特殊前缀的文件名,用endswith判断更稳妥。
内容的提问来源于stack exchange,提问作者ptn96
相关产品推荐
相关产品推荐

