如何使用glob获取2018年之后修改的CSV文件列表?
结论
glob本身仅支持文件名的模式匹配,不支持基于修改时间、文件大小这类文件属性的筛选,修改时间的过滤必须通过遍历判断实现。- 你原来的代码性能低的核心问题不是循环本身,是存在很多不必要的重复IO操作:排序时给全量文件(包含非CSV)查询了一次修改时间,循环判断时又查询了一次,远程目录的IO延迟会把这部分开销放大很多。
优化实现
你可以用如下逻辑优化,性能会有明显提升:
- 先用
Path.glob直接筛出所有CSV文件,避免遍历其他后缀的无效文件 - 单次查询修改时间,避免重复IO
- 增加正则匹配的异常校验,避免不符合命名规则的文件导致程序报错
import os import re from datetime import datetime from pathlib import Path TARGET_YEAR = 2018 # 提前转成时间戳,避免循环里重复计算 CUTOFF_TIME = datetime(TARGET_YEAR, 1, 1).timestamp() directory = Path("你的远程目录路径") final = [] # 预编译正则,提升匹配效率 name_pattern = re.compile(r'[a-z]+[0-9]{4}\.csv') for file in directory.glob("*.csv"): # 只调用一次getmtime,同时直接用时间戳比较,省去循环里每次转datetime的开销 if os.path.getmtime(file) >= CUTOFF_TIME: match_res = name_pattern.match(file.name) if match_res: final.append(match_res.group(0))
如果你偏好列表推导式的写法,也可以写成:
from datetime import datetime from pathlib import Path import re import os CUTOFF_TIME = datetime(2018, 1, 1).timestamp() name_pattern = re.compile(r'[a-z]+[0-9]{4}\.csv') final = [ name_pattern.match(f.name).group(0) for f in Path(directory).glob("*.csv") if os.path.getmtime(f) >= CUTOFF_TIME and name_pattern.match(f.name) ]
额外优化建议
如果你的远程目录是挂载到本地的网络盘,还可以考虑批量获取文件属性的工具进一步降低IO开销,普通场景下上面的写法已经足够处理10000个文件的量级。
内容的提问来源于stack exchange,提问作者Jeeva Bharathi
相关产品推荐
相关产品推荐

