2013-08-23 63 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']