我正在编写一个脚本,以递归地遍历主文件夹中的子文件夹,并构建一个特定文件类型的列表。我对剧本有点意见。目前设置如下:
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循环,并加入路径的第一部分,但我想我会仔细检查,看看是否有人有任何建议之前。
您应该使用称为root的dirpath。提供了dirnames,因此如果有不希望操作的文件夹,您可以删除它。递归入。
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']
编辑:
在最近的反对票之后,我突然意识到glob是一个更好的扩展选择工具。
import os
from glob import glob
result = [y for x in os.walk(PATH) for y in glob(os.path.join(x[0], '*.txt'))]
还有一个生成器版本
from itertools import chain
result = (chain.from_iterable(glob(os.path.join(x[0], '*.txt')) for x in os.walk('.')))
用于Python 3.4+的Edit2
from pathlib import Path
result = list(Path(".").rglob("*.[tT][xX][tT]"))
这不是最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']