如何在Python中高效查找索引已知、扩展名未知的文件
方案评估
- glob匹配方案:你的判断完全正确,glob每次查询都会全量遍历目录下所有文件做模式匹配,文件量过万的场景下单次查询延迟会达到毫秒甚至十毫秒级,完全不满足高频调用需求,直接排除。
- 预存索引字典方案:这个方案并没有你认为的那么“重量级”。如果目录下的文件不会动态增删改,这是效率最高的方案:Python加载一个10万键的字典耗时仅几毫秒,内存占用也只有几MB,单次查询是O(1)的,完全适配高频调用场景。唯一需要考虑的是如果文件会动态变动,需要额外做索引同步逻辑,你可以根据自己的业务场景评估这部分成本。
- 遍历扩展名测试存在性方案:这个方案是动态文件场景下的最优解,你觉得怪异只是认知偏差。
os.path.exists或者Path.exists()是内核级的系统调用,性能极高,只要你的允许扩展名列表长度在10以内,单次查询最多10次极快的系统调用,性能比glob遍历全目录高几个数量级,而且不需要维护额外的缓存,完全适配文件动态变动的场景。
推荐实现
场景1:目录文件静态(无频繁增删改)
优先使用预存索引方案,初始化时遍历一次目录生成索引即可,示例代码如下:
from pathlib import Path FILE_DIR = Path("/path/to/your/target/directory") # 初始化索引,仅执行一次 file_index = {} for file in FILE_DIR.iterdir(): if file.is_file(): try: idx = int(file.stem) file_index[idx] = file.name except ValueError: # 跳过不符合命名规则的文件 pass # 高频查询接口,O(1)效率 def get_file_by_index(i: int): return file_index.get(i)
如果需要持久化索引,存成JSON或者pickle文件都可以,程序启动时加载一次即可,几乎没有额外负担。
场景2:目录文件动态变动,或允许的扩展名数量少
优先使用遍历扩展名测试方案,示例代码如下:
from pathlib import Path from functools import lru_cache FILE_DIR = Path("/path/to/your/target/directory") # 替换为你的业务允许的所有扩展名 ALLOWED_EXTS = {"pdf", "png", "jpg", "txt", "docx", "xlsx"} # 加LRU缓存优化高频查询性能,maxsize可根据业务热点数量调整 @lru_cache(maxsize=2000) def get_file_by_index(i: int): for ext in ALLOWED_EXTS: target_file = FILE_DIR / f"{i}.{ext}" if target_file.exists(): return target_file.name # 不存在的结果也缓存,避免重复无效查询 return None # 如果文件有变动,调用此方法清空缓存即可 # get_file_by_index.cache_clear()
内容的提问来源于stack exchange,提问作者Domino
相关产品推荐
相关产品推荐

