我有一个文件扩展名列表,我必须编写 if 条件。类似的东西
ext = (".dae", ".xml", ".blend", ".bvh", ".3ds", ".ase",
".obj", ".ply", ".dxf", ".ifc", ".nff", ".smd",
".vta", ".mdl", ".md2", ".md3",
".pk3", ".mdc", ".x",
".q3o", ".q3s", ".raw",
".ac", ".dxf", ".irrmesh",
".irr", ".off", ".ter",
".mdl", ".hmp", ".mesh.xml",
".skeleton.xml", ".material", ".ms3dv",
".lwo", ".lws", ".lxo",
".csm", ".cob", ".scn",
".xgl", ".zgl")
for folder, subfolders, filename in os.walk(directory):
if any([filename.endswith(tuple(ext)) for filename in filenames]):
我意识到
endswith
区分大小写。例如,我如何将“.xml”和“.XML”视为相同的扩展名?
只需在调用 lower
之前调用
endswith
将字符串变为小写即可:
ext = (".dae", ".xml", ".blend", ".bvh", ".3ds", ".ase",
".obj", ".ply", ".dxf", ".ifc", ".nff", ".smd",
".vta", ".mdl", ".md2", ".md3"
".pk3", ".mdc", ".x"
".q3o", ".q3s", ".raw"
".ac", ".dxf", ".irrmesh"
".irr", ".off", ".ter"
".mdl", ".hmp", ".mesh.xml"
".skeleton.xml", ".material", ".ms3dv"
".lwo", ".lws", ".lxo"
".csm", ".cob", ".scn"
".xgl", ".zgl")
for folder, subfolders, filename in os.walk(directory):
if any([filename.lower().endswith(tuple(ext)) for filename in filenames]):
这是一个非常古老的答案,但从 Python 3.3 开始,存在
casefold()
方法,它比 lower()
更激进,并且是更自然的无大小写字符串匹配。所以像下面这样的东西是一个选择:
filename.casefold().endswith(ext)
顺便说一句,
any()
会短路,这意味着它会在第一个 True 处停止,因此如果在生成器表达式而不是列表上调用any()
,速度会快得多(特别是如果匹配字符串位于开头)一个长列表)因为使用geneexpr,我们可以立即停止endswith
检查,而使用list,我们必须在endswith
评估之前对每个字符串执行any()
检查。
所以而不是
any([filename.lower().endswith(ext) for filename in filenames])
# ^ ^ <--- list
使用
any(filename.lower().endswith(ext) for filename in filenames)
# ^ ^ <--- genexpr
最后,由于这个问题被标记为正则表达式,因此这里还有一个正则表达式解决方案。只需编译一个忽略大小写的模式并搜索该模式是否匹配即可。
import re
pat = re.compile(fr"({'|'.join(re.escape(e) for e in ext)})$", re.I)
for folder, subfolders, filenames in os.walk('.'):
if any(pat.search(filename) for filename in filenames):
# do something