如何在Python 3.10.6中排序os.walk结果,让副本紧跟原文件?
修改Python 3.10.6中os.walk的文件排序规则
问题场景
你需要的目标排序结果:
IMG0001.jpg IMG0002.jpg IMG0002(1).jpg IMG0002(2).jpg IMG0003.jpg
但os.walk默认排序(基于ASCII码)会得到:
IMG0001.jpg IMG0002(1).jpg IMG0002(2).jpg IMG0002.jpg IMG0003.jpg
原因是ASCII码中(的优先级高于.,导致带(n)的副本排在原文件前面。
解决方案:自定义排序Key
通过给sorted()方法传入自定义排序函数,重新定义文件名的排序逻辑,让原文件优先于同名副本,副本按编号递增排列。
1. 编写自定义排序键函数
import os import re def custom_sort_key(filename): # 匹配格式为"文件名(n).扩展名"的副本文件 copy_match = re.match(r'^(.*?)\((\d+)\)(\.[^.]+)$', filename) if copy_match: # 提取基础文件名(含扩展名)和副本编号 base_filename = copy_match.group(1) + copy_match.group(3) copy_number = int(copy_match.group(2)) return (base_filename, copy_number) else: # 原文件的副本编号设为0,确保排在同名副本前 return (filename, 0)
2. 在os.walk中应用排序
遍历目录时,对os.walk返回的文件列表使用自定义规则排序:
target_path = "/your/target/directory" # 替换为你的目标路径 for root, dirs, files in os.walk(target_path): # 按自定义规则排序文件 sorted_files = sorted(files, key=custom_sort_key) # 处理排序后的文件列表(示例:打印文件路径) for file in sorted_files: print(os.path.join(root, file))
逻辑说明
- 正则表达式
^(.*?)\((\d+)\)(\.[^.]+)$会匹配带数字编号的副本文件,提取出原文件的基础名称、副本编号和扩展名。 - 原文件的排序键为
(文件名, 0),副本的排序键为(原文件名, 副本编号),这样同名的原文件会因为编号0优先于所有带正编号的副本,副本则按编号从小到大排列。 - 不同名称的文件仍会按基础文件名的自然顺序排序。
内容的提问来源于stack exchange,提问作者Lightmaster
相关产品推荐
相关产品推荐

