2013-08-23 65 views
48

我正在处理脚本以递归方式遍历主文件夹中的子文件夹并从某个文件类型构建一个列表。我遇到了该脚本的问题。它目前如下递归子文件夹搜索和返回列表中的文件python

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循环,并加入路径的第一部分,但我想到了Id仔细检查,看看有没有人有任何建议。谢谢你的帮助!

回答

83

您应该使用dirpath,您可以拨打rootdirnames提供,所以你可以修剪它,如果有文件夹,你不希望os.walk递归到。

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

编辑:

最新downvote后,它发生,我认为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('.'))) 
+0

如果它不是一个列表理解,这将更具可读性...... –

19

Changed in Python 3.5: Support for recursive globs using “**”.

glob.glob()有一个新的recursive parameter

如果你想获得my_path下每.txt文件(递归的包含子目录):

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=False): 
    # ... 
+1

TypeError:glob()得到了一个意外的关键字参数'递归' – CyberJacob

+0

它应该工作。确保你使用的版本> = 3.5。我在我的答案中添加了一个链接,以获取更多详细信息。 – Rotareti

+0

这就是为什么,我在2.7 – CyberJacob

2

它不是大部分pythonic答案,但我会把它放在这里为乐趣,因为这是一个递归的教训

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 

在我的机器我有两个文件夹,rootroot2

[email protected] ]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']