寻求高效查找文件路径/文件名中序列的优化实现方案
高效文件序列检测优化方案
我完全懂你现在的痛点——原代码在文件数量上来之后性能跳水,核心问题在于它的双重循环遍历+重复的数字匹配校验,当文件变多时间复杂度会逼近O(n²),自然越来越慢。咱们换个模板分组的思路,既能把时间复杂度降到O(n)级别,代码也会更简洁直观。
核心优化思路
- 对每个文件路径,一次性提取所有连续数字段的位置和内容;
- 针对每个数字段生成对应的「特征模板」:把该数字段替换成统一占位符(比如
{SEQ}),同时记录这个数字段在原路径的起止位置; - 用字典做分组,键是**(模板字符串, 数字段位置, 数字段长度)**,值是属于该序列的文件列表——同一序列的文件必然共享同一个模板(除了固定位置的数字段);
- 最后过滤掉只有单个文件的组,转换成你需要的输出格式。
实现代码
import os import re def detect_sequences(filepaths): # 匹配所有连续数字段的正则 num_pattern = re.compile(r'\d+') seq_groups = {} for filepath in filepaths: # 获取当前路径中所有数字段的位置信息 matches = list(num_pattern.finditer(filepath)) for match in matches: start, end = match.span() # 生成替换当前数字段后的模板字符串 template = filepath[:start] + '{SEQ}' + filepath[end:] # 用(模板, 数字段位置)作为分组键,确保同序列文件被归为一组 group_key = (template, start, end) # 将当前文件加入对应分组 if group_key not in seq_groups: seq_groups[group_key] = [] seq_groups[group_key].append(filepath) # 转换为要求的输出格式,过滤单文件组 result = [] for (template, start, end), files in seq_groups.items(): if len(files) >= 2: # 按序列数字值排序(可选,让输出更符合逻辑) def get_seq_num(f): return int(f[start:end]) sorted_files = sorted(files, key=get_seq_num) result.append([sorted_files, (start, end)]) return result def main(dir_path): filepaths = [ os.path.join(dir_path, filename) for filename in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, filename)) ] seqs = detect_sequences(filepaths) for seq in seqs: print(seq) if __name__ == "__main__": main(r"C:\path\to\sequence_folder")
关键细节说明
- 一次性提取数字段:用
re.finditer批量获取路径中所有数字的位置,避免重复正则匹配的开销; - 精准分组逻辑:只有当两个文件除了某个固定长度的数字段外完全相同时,才会被分到同一组,完美符合你要求的「序列长度一致、允许间隔」规则;
- 高效分组操作:字典的查找和插入都是O(1)操作,整个预处理过程是O(n*m)(m是单文件的数字段数量,通常很小),远优于原代码的O(n²);
- 可选排序:按序列数字值排序后,输出的文件列表会更符合常规的序列逻辑。
性能对比
- 原代码:文件数量为N时,时间复杂度约为O(N²),每个文件要和现有所有序列逐一比对;
- 新方案:时间复杂度约为O(N*M),M是单文件的数字段数量(通常为2-3个),当N很大时,性能提升会非常显著。
用你给出的示例输入测试,新代码会快速把abc08/09/10等分到同一模板组,把fde302be/305be/309be等分到另一模板组,完全匹配你的期望输出。
内容的提问来源于stack exchange,提问作者user-ab
相关产品推荐
相关产品推荐

