在Python中列出具有指定深度的目录

时间:2011-08-23 10:28:06

标签: python

我想要一个函数来返回一个包含指定路径和固定深度的目录的列表,并很快意识到有一些替代方案。我正在使用os.walk但是在计算深度等时代码开始看起来很难看。

什么是最“整洁”的实施?

5 个答案:

答案 0 :(得分:46)

如果深度固定,glob是个好主意:

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

否则,使用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)

答案 1 :(得分:3)

这不完全是 neat ,但在类UNIX操作系统下,您还可以依赖像“find”这样的系统工具,并将其作为外部程序执行,例如:

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

然后,您可以将输出重定向到某个字符串变量以进行进一步处理。

答案 2 :(得分:2)

我真的很喜欢phihag的回答。我根据自己的需要调整了它。

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

我想我也可以用这样的东西制作它:

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

批评欢迎。

答案 3 :(得分:2)

使用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)

答案 4 :(得分:-1)

这是pathlib的实现:

from pathlib import Path

def get_files(path, mask, depth):
    for i in range(1, depth + 1):
        for f in Path(path).glob('/'.join('*' * i) + '/' + mask):
            yield f

样品用量:

for i in get_files('testdir', '*.txt', 1):
    print(i)
>>>
testdir/a/a.txt
testdir/b/b.txt
testdir/c/c.txt

for i in get_files('testdir', '*.txt', 2):
    print(i)
>>>
testdir/a/a.txt
testdir/b/b.txt
testdir/c/c.txt
testdir/a/aa/aa.txt
testdir/b/bb/bb.txt
testdir/c/cc/cc.txt