Recursive sub folder search and return files in a list python
我正在编写一个脚本,递归地遍历主文件夹中的子文件夹,并根据某个文件类型构建一个列表。我对剧本有意见。其当前设置如下
1 2 3 4 | for root, subFolder, files in os.walk(PATH): for item in files: if item.endswith(".txt") : fileNamePath = str(os.path.join(root,subFolder,item)) |
问题是子文件夹变量正在拉入子文件夹列表,而不是项目文件所在的文件夹。我之前在考虑为子文件夹运行for循环,并加入路径的第一部分,但是我想再次检查一下是否有人在此之前有任何建议。谢谢你的帮助!
你应该使用你称之为
1 2 | import os result = [os.path.join(dp, f) for dp, dn, filenames in os.walk(PATH) for f in filenames if os.path.splitext(f)[1] == '.txt'] |
编辑:
在最近一次投票否决之后,我突然想到,
1 2 3 | import os from glob import glob result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], '*.txt'))] |
也是发电机版本
1 2 | from itertools import chain result = (chain.from_iterable(glob(os.path.join(x[0], '*.txt')) for x in os.walk('.'))) |
针对python 3.4的edit2+
1 2 | from pathlib import Path result = list(Path(".").rglob("*.[tT][xX][tT]")) |
Changed in Python 3.5: Support for recursive globs using"**".
如果要获取
1 2 3 4 5 6 7 | 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作为替代:
1 2 | for file in glob.iglob(my_path, recursive=False): # ... |
我会把约翰·拉罗伊的清单理解翻译成嵌套的for,以防其他人无法理解。
1 | result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], '*.txt'))] |
应等于:
1 2 3 4 5 | result = [] for x in os.walk(PATH): for y in glob(os.path.join(x[0], '*.txt')): result.append(y) |
以下是列表理解和os.walk和glob.glob函数的文档。
这不是最简单的Python式的答案,但我会把它放在这里玩,因为这是一个很好的递归课程。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
在我的机器上,我有两个文件夹:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 |
假设我想在这些目录中找到所有
1 2 3 4 5 6 7 8 9 | 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'] |
新的
1 2 | from pathlib import Path result = list(Path(PATH).glob('**/*.txt')) |
您还可以使用生成器版本:
1 2 3 | from pathlib import Path for file in Path(PATH).glob('**/*.txt'): pass |
这将返回