如何在Python中列出目录中的所有文件并将其添加到列表中?


当前回答

从3.4版开始,有内置的迭代器,比os.listdir()高效得多:

pathlib:3.4版新增。

>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]

根据PEP428,pathlib库的目的是提供一个简单的类层次结构来处理文件系统路径和用户对它们进行的常见操作。

os.scandir():3.5版新增。

>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]

注意,os.walk()使用os.scandir()而不是3.5版的os.listdir(),根据PEP471,它的速度提高了2-20倍。

让我也推荐阅读ShadowRanger在下面的评论。

其他回答

一位聪明的老师曾经告诉我:

当有几种既定的方法来做某事时,没有一种方法对所有情况都有好处。

因此,我将为问题的一个子集添加一个解决方案:通常,我们只想检查文件是否匹配开始字符串和结束字符串,而不需要进入子目录。因此,我们需要一个返回文件名列表的函数,例如:

filenames = dir_filter('foo/baz', radical='radical', extension='.txt')

如果您想首先声明两个函数,可以这样做:

def file_filter(filename, radical='', extension=''):
    "Check if a filename matches a radical and extension"
    if not filename:
        return False
    filename = filename.strip()
    return(filename.startswith(radical) and filename.endswith(extension))

def dir_filter(dirname='', radical='', extension=''):
    "Filter filenames in directory according to radical and extension"
    if not dirname:
        dirname = '.'
    return [filename for filename in os.listdir(dirname)
                if file_filter(filename, radical, extension)]

这个解决方案可以很容易地用正则表达式来概括(如果您不希望模式总是停留在文件名的开头或结尾,您可能需要添加一个模式参数)。

如果您正在寻找find的Python实现,这是我经常使用的方法:

from findtools.find_files import (find_files, Match)

# Recursively find all *.sh files in **/usr/bin**
sh_files_pattern = Match(filetype='f', name='*.sh')
found_files = find_files(path='/usr/bin', match=sh_files_pattern)

for found_file in found_files:
    print found_file

所以我用它制作了一个PyPI包,还有一个GitHub存储库。我希望有人发现它对这段代码可能有用。

我将提供一个示例单行,其中可以提供源路径和文件类型作为输入。代码返回带有csv扩展名的文件名列表。使用以防需要返回所有文件。这还将递归扫描子目录。

[y代表os.walk中的x(sourcePath)代表glob中的y(os.path.join(x[0],'*.csv'))]

根据需要修改文件扩展名和源路径。

这是我的通用函数。它返回文件路径列表而不是文件名,因为我发现这更有用。它有几个可选的参数,使其具有通用性。例如,我经常将其与pattern=“*.txt”或subfolders=True等参数一起使用。

import os
import fnmatch

def list_paths(folder='.', pattern='*', case_sensitive=False, subfolders=False):
    """Return a list of the file paths matching the pattern in the specified 
    folder, optionally including files inside subfolders.
    """
    match = fnmatch.fnmatchcase if case_sensitive else fnmatch.fnmatch
    walked = os.walk(folder) if subfolders else [next(os.walk(folder))]
    return [os.path.join(root, f)
            for root, dirnames, filenames in walked
            for f in filenames if match(f, pattern)]

从3.4版开始,有内置的迭代器,比os.listdir()高效得多:

pathlib:3.4版新增。

>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]

根据PEP428,pathlib库的目的是提供一个简单的类层次结构来处理文件系统路径和用户对它们进行的常见操作。

os.scandir():3.5版新增。

>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]

注意,os.walk()使用os.scandir()而不是3.5版的os.listdir(),根据PEP471,它的速度提高了2-20倍。

让我也推荐阅读ShadowRanger在下面的评论。