如何仅调用一次glob函数匹配多种文件夹模式查找对应文件
问题解答
可以单次调用glob实现需求
你之前尝试的*[type1, type2]*/*语法是错误的:方括号[]在glob匹配规则里是单字符匹配集,仅能匹配方括号内包含的任意单个字符,你写的这个规则实际会匹配名称中包含t、y、p、e、1、2、逗号、空格中任意字符的文件夹,和你要匹配完整type1/type2字符串的需求完全不符。
正确的写法需要用到glob的大括号扩展语法,Python 3.11及以上版本原生支持该特性,写法如下:
import glob # 注意大括号内多个匹配项之间不要加空格,expand_braces参数用于开启大括号扩展 files = glob.glob('*{type1,type2}*/*', expand_braces=True)
如果你的两个匹配规则确实只有末尾数字不同,也可以简化为兼容性更好的写法,不需要依赖高版本的大括号扩展:
files = glob.glob('*type[12]*/*')
方括号[12]表示匹配1或2任意一个数字,完全符合你的场景。
单次调用性能优于两次调用
是的,单次调用的性能会更高:
- 两次调用glob时,会对当前工作目录执行两次全量遍历,分别筛选名称带
type1和type2的文件夹,再分别遍历这些文件夹拉取下属文件 - 单次调用glob时,仅需对当前工作目录执行一次全量遍历,同时匹配两种名称规则的文件夹,再统一遍历拉取下属文件
当前目录下的文件、文件夹数量越多,单次调用的性能优势越明显。
低Python版本兼容方案
如果你使用的是Python 3.10及以下版本,glob原生不支持大括号扩展,除了保持原来的两次调用写法外,也可以通过正则匹配自行实现单次遍历,示例如下:
import os import re pattern = re.compile(r'.*type(1|2).*') files = [] for entry in os.scandir(): if entry.is_dir() and pattern.match(entry.name): files.extend(os.path.join(entry.name, f) for f in os.listdir(entry.path) if os.path.isfile(os.path.join(entry.path, f)))
该写法性能和高版本的单次glob调用基本持平,但代码复杂度更高,低版本场景下更推荐保持原来的两次glob写法,可读性更好。
内容的提问来源于stack exchange,提问作者prody
相关产品推荐
相关产品推荐

