使用fnmatch.filter按多个文件扩展名过滤文件

42 投票
10 回答
59802 浏览
提问于 2025-04-16 13:57

给定以下这段Python代码:

for root, dirs, files in os.walk(directory):
    for filename in fnmatch.filter(files, '*.png'):
        pass

我该如何筛选多个文件扩展名呢?在这个特殊情况下,我想获取所有以*.png、*.gif、*.jpg或*.jpeg结尾的文件。

目前我想到的是:

for root, dirs, files in os.walk(directory):
    for extension in ['jpg', 'jpeg', 'gif', 'png']:
        for filename in fnmatch.filter(files, '*.' + extension):
            pass

但我觉得这个方法不是很优雅,也不够高效。

有没有人有更好的主意呢?

10 个回答

6

这样做可能会更好,因为你没有反复调用 +,而是用 tuple 代替了 list

for root, dirs, files in os.walk(directory):
    for extension in ('*.jpg', '*.jpeg', '*.gif', '*.png'):
        for filename in fnmatch.filter(files, extension):
            pass

tuple 更好是因为一旦你创建了它们,就不打算修改它们。你只是用它们来遍历。

9

我觉得你的代码其实没问题。如果你想每个文件名只处理一次,可以自己定义一个过滤函数:

def is_image_file(filename, extensions=['.jpg', '.jpeg', '.gif', '.png']):
    return any(filename.endswith(e) for e in extensions)

for root, dirs, files in os.walk(directory):
    for filename in filter(is_image_file, files):
        pass
55

如果你只需要检查文件的扩展名(也就是不需要更复杂的匹配),那为什么不直接用简单的字符串操作呢?

for root, dirs, files in os.walk(directory):
    for filename in files:
        if filename.endswith(('.jpg', '.jpeg', '.gif', '.png')):
            pass

撰写回答