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


当前回答

Python 3.4+的另一个非常可读的变体是使用pathlib.Path.glob:

from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]

更具体一些很简单,例如,只在所有子目录中查找非符号链接的Python源文件:

[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]

其他回答

使用发电机

import os
def get_files(search_path):
     for (dirpath, _, filenames) in os.walk(search_path):
         for filename in filenames:
             yield os.path.join(dirpath, filename)
list_files = get_files('.')
for filename in list_files:
    print(filename)

如果您正在寻找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存储库。我希望有人发现它对这段代码可能有用。

import os
import os.path


def get_files(target_dir):
    item_list = os.listdir(target_dir)

    file_list = list()
    for item in item_list:
        item_dir = os.path.join(target_dir,item)
        if os.path.isdir(item_dir):
            file_list += get_files(item_dir)
        else:
            file_list.append(item_dir)
    return file_list

这里我使用递归结构。

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

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

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

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)]

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

从目录及其所有子目录获取完整文件路径

import os

def get_filepaths(directory):
    """
    This function will generate the file names in a directory 
    tree by walking the tree either top-down or bottom-up. For each 
    directory in the tree rooted at directory top (including top itself), 
    it yields a 3-tuple (dirpath, dirnames, filenames).
    """
    file_paths = []  # List which will store all of the full filepaths.

    # Walk the tree.
    for root, directories, files in os.walk(directory):
        for filename in files:
            # Join the two strings in order to form the full filepath.
            filepath = os.path.join(root, filename)
            file_paths.append(filepath)  # Add it to the list.

    return file_paths  # Self-explanatory.

# Run the above function and store its results in a variable.   
full_file_paths = get_filepaths("/Users/johnny/Desktop/TEST")

我在上述函数中提供的路径包含3个文件,其中两个位于根目录中,另一个位于名为“subfolder”的子文件夹中打印将打印列表的完整文件路径:['/Users/johnny/Desktop/TEST/file1.txt','/Users/johnny/Desctop/TEST-file2.txt','/Users/johnny/Desktop/STEST/SUBFOLDER/file3.dat']

如果愿意,您可以打开并阅读内容,或者只关注扩展名为“.dat”的文件,如下面的代码所示:

for f in full_file_paths:
  if f.endswith(".dat"):
    print f

/用户/johnny/Desktop/TEST/SUBFOLDER/file3.dat