我正在编写一个脚本,以递归地遍历主文件夹中的子文件夹,并构建一个特定文件类型的列表。我对剧本有点意见。目前设置如下:

for root, subFolder, files in os.walk(PATH):
    for item in files:
        if item.endswith(".txt") :
            fileNamePath = str(os.path.join(root,subFolder,item))

问题是subFolder变量拉入的是子文件夹列表,而不是ITEM文件所在的文件夹。我在考虑之前运行子文件夹的for循环,并加入路径的第一部分,但我想我会仔细检查,看看是否有人有任何建议之前。


当前回答

如果你不介意安装一个额外的灯光库,你可以这样做:

pip install plazy

用法:

import plazy

txt_filter = lambda x : True if x.endswith('.txt') else False
files = plazy.list_files(root='data', filter_func=txt_filter, is_include_root=True)

结果应该是这样的:

['data/a.txt', 'data/b.txt', 'data/sub_dir/c.txt']

它可以在Python 2.7和Python 3上运行。

Github: https://github.com/kyzas/plazy文件

免责声明:我是plazy的作者。

其他回答

这不是最python的答案,但我把它放在这里是为了好玩,因为这是递归的一课

def find_files( files, dirs=[], extensions=[]):
    new_dirs = []
    for d in dirs:
        try:
            new_dirs += [ os.path.join(d, f) for f in os.listdir(d) ]
        except OSError:
            if os.path.splitext(d)[1] in extensions:
                files.append(d)

    if new_dirs:
        find_files(files, new_dirs, extensions )
    else:
        return

在我的机器上有两个文件夹,root和root2

mender@multivax ]ls -R root root2
root:
temp1 temp2

root/temp1:
temp1.1 temp1.2

root/temp1/temp1.1:
f1.mid

root/temp1/temp1.2:
f.mi  f.mid

root/temp2:
tmp.mid

root2:
dummie.txt temp3

root2/temp3:
song.mid

假设我想在这两个目录中找到所有。txt和。mid文件,然后我就可以

files = []
find_files( files, dirs=['root','root2'], extensions=['.mid','.txt'] )
print(files)

#['root2/dummie.txt',
# 'root/temp2/tmp.mid',
# 'root2/temp3/song.mid',
# 'root/temp1/temp1.1/f1.mid',
# 'root/temp1/temp1.2/f.mid']

在Python 3.5更改:支持使用" ** "的递归glob。

Glob.glob()有一个新的递归参数。

如果你想获取my_path下的每个.txt文件(递归地包括subdirs):

import glob

files = glob.glob(my_path + '/**/*.txt', recursive=True)

# my_path/     the dir
# **/       every file and dir under my_path
# *.txt     every file that ends with '.txt'

如果你需要一个迭代器,你可以使用iglob作为替代:

for file in glob.iglob(my_path, recursive=True):
    # ...

您可以通过这种方式返回绝对路径文件的列表。

def list_files_recursive(path):
    """
    Function that receives as a parameter a directory path
    :return list_: File List and Its Absolute Paths
    """

    import os

    files = []

    # r = root, d = directories, f = files
    for r, d, f in os.walk(path):
        for file in f:
            files.append(os.path.join(r, file))

    lst = [file for file in files]
    return lst


if __name__ == '__main__':

    result = list_files_recursive('/tmp')
    print(result)

新的pathlib库将其简化为一行:

from pathlib import Path
result = list(Path(PATH).glob('**/*.txt'))

你也可以使用生成器版本:

from pathlib import Path
for file in Path(PATH).glob('**/*.txt'):
    pass

这将返回Path对象,您可以将其用于几乎任何事情,或者通过file.name获取文件名作为字符串。

最简单最基本的方法:

import os
for parent_path, _, filenames in os.walk('.'):
    for f in filenames:
        print(os.path.join(parent_path, f))