如何一次获取符合fnmatch过滤的文件计数与文件路径
优化方案:单次遍历同时获取文件计数与路径
先修正原代码的两个问题
- return_ext函数逻辑错误:原函数的循环毫无意义,会直接返回列表第一个元素
AAAAA.txt,无法匹配多个规则。如果需要匹配多个文件名模式,应该返回整个模式列表。 - 重复遍历目录:两次调用
os.walk会重复扫描目录结构,浪费资源,合并为一次遍历即可同时完成计数和路径收集。
优化后的代码
import os import fnmatch from pathlib import Path def get_match_patterns(): # 返回所有需要匹配的fnmatch模式 return ["AAAAA.txt", "BBBBBB.txt"] def collect_files_and_count(root_path): patterns = get_match_patterns() file_paths = [] count = 0 for dirpath, _, filenames in os.walk(root_path): for filename in filenames: # 检查文件名是否匹配任意一个规则 if any(fnmatch.fnmatch(filename, pattern) for pattern in patterns): full_path = str(Path(dirpath) / filename) file_paths.append(full_path) count += 1 return count, file_paths # 使用示例 file_path = "./your_target_directory" # 替换为你的目标目录 total_count, found_files = collect_files_and_count(file_path) # 输出结果 print(f"找到符合规则的文件总数:{total_count}") print("文件路径列表:") for path in found_files: print(path)
代码说明
- 单次遍历:通过一次
os.walk扫描目录,在遍历过程中同时完成文件匹配、路径收集和计数,避免重复IO操作。 - 多规则匹配:使用
any()结合fnmatch.fnmatch实现多个模式的匹配,解决原代码只能匹配单个规则的问题。 - 路径处理:用
Path拼接路径更简洁可靠,替代os.path.join的写法。
可选优化:生成器版本(适合大目录)
如果目标目录文件数量极大,不想一次性加载所有路径到内存,可以用生成器同时返回计数和路径流:
def collect_files_and_count_generator(root_path): patterns = get_match_patterns() count = 0 for dirpath, _, filenames in os.walk(root_path): for filename in filenames: if any(fnmatch.fnmatch(filename, pattern) for pattern in patterns): full_path = str(Path(dirpath) / filename) count += 1 yield full_path, count # 遍历结束后返回最终计数 yield None, count # 使用示例 file_path = "./your_target_directory" gen = collect_files_and_count_generator(file_path) total_count = 0 print("文件路径列表:") for path, current_count in gen: if path is None: total_count = current_count continue print(path) print(f"\n找到符合规则的文件总数:{total_count}")
内容的提问来源于stack exchange,提问作者Massimo B.
相关产品推荐
相关产品推荐

