2013-06-19 23 views
0

我想創建一個函數,它接受一個根文件的名稱,然後遍歷導演並返回一個像這樣的列表。Python文件橫向

[["folder1",[ 
    ["subfolder1",[ 
     "file1", 
     "file2" 
    ]], 
    ["subfolder2",[ 
     "file3", 
     "file4" 
    ]] 
],"file5","file6"] 

下面是我在函數嘗試:

def traverse(rootdir): 
    names = [] 
    for cdirname, dirnames, filenames in os.walk(rootdir): 
     # record path to all subdirectories first. 
     for subdirname in dirnames: 
      names.append([subdirname,traverse(os.path.join(cdirname, subdirname))]) 

     # record path to all filenames. 
     for filename in filenames: 
      names.append(os.path.join(cdirname, filename)) 

    return names 

我的問題是,我最後總是得到相同的文件/文件夾的複製被記錄的功能,我的路徑是永遠相對於「rootdir」而不是相應文件/文件夾的名稱顯示。我如何清除重複項?另外我怎麼能做到這一點,以便它不是記錄的完整路徑。

在此先感謝。

+1

如果'filename',而不是'os.path.join(cdirname,文件名)'那麼你沒有得到完整的路徑。 – SethMMorton

+0

謝謝,這對我來說應該是顯而易見的!不知道爲什麼我沒有看到! –

回答

1

sorted用於使目錄優先。如果您不介意該訂單,只需返回names

def traverse(rootdir): 
    names = [] 
    dirs, files = [], [] 
    for filename in os.listdir(rootdir): 
     filepath = os.path.join(rootdir, filename) 
     if os.path.isdir(filepath): 
      names.append([filename, traverse(filepath)]) 
     else: 
      names.append(filename) 
    return sorted(names, key=lambda x: (0, x[0]) if isinstance(x, list) else (1, x)) 

使用os.walk另一個版本:

def traverse(rootdir): 
    names = [] 
    dir_to_names = {rootdir: names} 
    for cdirname, dirnames, filenames in os.walk(rootdir): 
     subnames = dir_to_names[cdirname] 
     for subdirname in sorted(dirnames): 
      subnames2 = dir_to_names[os.path.join(cdirname, subdirname)] = [] 
      subnames.append([subdirname, subnames2]) 
     for filename in sorted(filenames): 
      subnames.append(filename) 
    return names 
0

您可以使用os.walk()來獲取所有的子文件和子文件。它返回一個包含「三元組」(('當前路徑',[子],[子文件])的列表。但是這並不符合我的需要,所以我編寫了下面的腳本。希望這可以幫助。

它的功能是爲每個包含文件和目錄的文件夾創建一個對象,並按字母順序對它們進行排序。我看着os.walk和它是如何工作的,這是一個類似的方法(用isdir())。 tab變量只是爲了更好地看待輸出。

import os 


class Folder(): 
    """ Generate a tree list from a given directory """ 
    # List of prohibited_dirs folders on any levels 
    prohibited_dirs = set([]) 
    prohibited_files = set([]) 
    tab = 0 
    def __init__(self, path, folder_name): 
     """ path should be /home/example, folder_name: example """ 
     self.path = path 
     self.folder_name = folder_name 
     self.sub_dirs = [] 
     self.sub_files = [] 
     self.__class__.tab += 1 
     # print self.tab 

    def sorter(self): 
     """ sorts listdir output for folders and files""" 
     # Sort Folders and Files 
     names = os.listdir(self.path) 
     for name in names: 
      if os.path.isdir(os.path.join(self.path, name)): 
       self.sub_dirs.append(name) 
      else: 
       self.sub_files.append(name) 

    def list_stuff(self): 
     """ sort lists, and iterate overall subfolders/files.""" 
     # Sort alphabetically 
     self.sub_dirs.sort(key=str.lower) 
     self.sub_files.sort(key=str.lower) 
     # all subfolders, if is also break condition 
     if self.sub_dirs: 
      # Filter prohibited_dirs Folders 
      for sub_dir in self.sub_dirs: 
       if sub_dir in self.__class__.prohibited_dirs: 
        continue 
       print "\t" * self.tab + sub_dir 
       # Go deeper 
       deeper = Folder(os.path.join(self.path, sub_dir), sub_dir) 
       deeper.sorter() 
       deeper.list_stuff() 
       # Free object 
       del deeper 
       self.__class__.tab -= 1 
     # list all Files, if is also break condition 
     if self.sub_files: 
      for sub_file in self.sub_files: 
       if sub_file in self.__class__.prohibited_files: 
        continue 
       print "\t" * self.tab + sub_file 

STARTDIRECTORY = "." 
STARTFOLDER = "." 

runner = Folder(STARTDIRECTORY, STARTFOLDER) 
runner.sorter() 
runner.list_stuff()