【发布时间】:2011-08-23 10:28:06
【问题描述】:
我想要一个函数来返回一个包含具有指定路径和固定深度的目录的列表,并很快意识到有一些替代方案。我经常使用 os.walk,但是在计算深度等时代码开始看起来很丑。
真正最“整洁”的实现是什么?
【问题讨论】:
标签: python
我想要一个函数来返回一个包含具有指定路径和固定深度的目录的列表,并很快意识到有一些替代方案。我经常使用 os.walk,但是在计算深度等时代码开始看起来很丑。
真正最“整洁”的实现是什么?
【问题讨论】:
标签: python
如果深度是固定的,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)
【讨论】:
filesDepth3的定义中直接指定您的路径模式。如果您正在浏览大型文件夹数据库,则当前配置将花费很长时间。首先获取所有 3 级文件夹,然后按名称或内容过滤是次优资源使用。
这并不完全整洁,但是在类UNIX操作系统下,你也可以依赖“find”之类的系统工具,将其作为外部程序执行,例如:
from subprocess import call
call(["find", "-maxdepth", "2", "-type", "d"])
然后您可以将输出重定向到某个字符串变量以进行进一步处理。
【讨论】:
"-mindepth","2" 添加到调用参数列表中。
call("find -maxdepth 2 -mindepth 2 -type d", shell=True).
使用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)
【讨论】:
我真的很喜欢 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
欢迎批评。
【讨论】:
这是一个简单的函数
import os
from glob import glob
from pathlib import Path
def find_sub_dirs(path, depth=2):
path = Path(path)
assert path.exists(), f'Path: {path} does not exist'
depth_search = '*/' * depth
search_pattern = os.path.join(path, depth_search)
return list(glob(f'{search_pattern}'))
【讨论】: