Use fnmatch.filter to filter files by more than one possible file extension Use fnmatch.filter to filter files by more than one possible file extension python python

Use fnmatch.filter to filter files by more than one possible file extension


If you only need to check extensions (i.e. no further wildcards), why don't you simply use basic string operations?

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


I think your code is actually fine. If you want to touch every filename only once, define your own filtering function:

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


I've been using this with a lot of success.

import fnmatchimport functoolsimport itertoolsimport os# Remove the annotations if you're not on Python3def find_files(dir_path: str=None, patterns: [str]=None) -> [str]:    """    Returns a generator yielding files matching the given patterns    :type dir_path: str    :type patterns: [str]    :rtype : [str]    :param dir_path: Directory to search for files/directories under. Defaults to current dir.    :param patterns: Patterns of files to search for. Defaults to ["*"]. Example: ["*.json", "*.xml"]    """    path = dir_path or "."    path_patterns = patterns or ["*"]    for root_dir, dir_names, file_names in os.walk(path):        filter_partial = functools.partial(fnmatch.filter, file_names)        for file_name in itertools.chain(*map(filter_partial, path_patterns)):            yield os.path.join(root_dir, file_name)

Examples:

for f in find_files(test_directory):    print(f)

yields:

.\test.json.\test.xml.\test.ini.\test_helpers.py.\__init__.py

Testing with multiple patterns:

for f in find_files(test_directory, ["*.xml", "*.json", "*.ini"]):    print(f)

yields:

.\test.json.\test.xml.\test.ini