0

我正在尝试创建一个函数,该函数接受根文件的名称,然后遍历目录并返回这样的列表。

[["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”显示,而不仅仅是相应文件/文件夹的名称。如何清除重复项?此外,我怎样才能使它不是被记录的完整路径。

4

2 回答 2

1

sorted用于使目录排在第一位。如果你不介意那个顺序,就 return 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
于 2013-06-19T07:05:53.147 回答
0

您可以os.walk()用来获取所有子目录和子文件。它返回一个包含“三元组”的列表,其中包含 ('current path', [subdirs], [subfiles])。但这对我的需求不起作用,所以我编写了以下脚本。希望这可以帮助。

它的作用是,它为每个包含文件和目录的文件夹创建一个对象,并按字母顺序对它们进行排序。我查看了 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()
于 2013-06-19T06:47:59.653 回答