List directories with a specified depth in Python

后端 未结 4 1560
故里飘歌
故里飘歌 2020-12-28 14:26

I\'m want a function to return a list with directories with a specified path and a fixed depth and soon realized there a few alternatives. I\'m using os.walk quite a lot but

相关标签:
4条回答
  • 2020-12-28 14:56

    A simple, recursive solution using os.scandir:

    def _walk(path, depth):
        """Recursively list files and directories up to a certain depth"""
        depth -= 1
        with os.scandir(path) as p:
            for entry in p:
                yield entry.path
                if entry.is_dir() and depth > 0:
                    yield from _walk(entry.path, depth)
    
    0 讨论(0)
  • 2020-12-28 15:10

    If the depth is fixed, glob is a good idea:

    import glob,os.path
    filesDepth3 = glob.glob('*/*/*')
    dirsDepth3 = filter(lambda f: os.path.isdir(f), filesDepth3)
    

    Otherwise, it shouldn't be too hard to use os.walk:

    import os,string
    path = '.'
    path = os.path.normpath(path)
    res = []
    for root,dirs,files in os.walk(path, topdown=True):
        depth = root[len(path) + len(os.path.sep):].count(os.path.sep)
        if depth == 2:
            # We're currently two directories in, so all subdirs have depth 3
            res += [os.path.join(root, d) for d in dirs]
            dirs[:] = [] # Don't recurse any deeper
    print(res)
    
    0 讨论(0)
  • 2020-12-28 15:10

    This is not exactly neat, but under UNIX-like OS, you could also rely on a system tool like "find", and just execute it as an external program, for example:

    from subprocess import call
    call(["find", "-maxdepth", "2", "-type", "d"])
    

    You can then redirect the output to some string variable for further handling.

    0 讨论(0)
  • 2020-12-28 15:22

    I really like phihag's answer. I adapted it to suit my needs.

    import fnmatch,glob
    def fileNamesRetrieve( top, maxDepth, fnMask  ):
        someFiles = []
        for d in range( 1, maxDepth+1 ):
            maxGlob = "/".join( "*" * d )
            topGlob = os.path.join( top, maxGlob )
            allFiles = glob.glob( topGlob )
            someFiles.extend( [ f for f in allFiles if fnmatch.fnmatch( os.path.basename( f ), fnMask ) ] )
        return someFiles
    

    I guess I could also make it a generator with something like this:

    def fileNamesRetrieve( top, maxDepth, fnMask  ):
        for d in range( 1, maxDepth+1 ):
            maxGlob = "/".join( "*" * d )
            topGlob = os.path.join( top, maxGlob )
            allFiles = glob.glob( topGlob )
            if fnmatch.fnmatch( os.path.basename( f ), fnMask ):
                yield f
    

    Critique welcome.

    0 讨论(0)
提交回复
热议问题