Ric*_*dle 217
import os
def get_immediate_subdirectories(a_dir):
return [name for name in os.listdir(a_dir)
if os.path.isdir(os.path.join(a_dir, name))]
Run Code Online (Sandbox Code Playgroud)
use*_*036 104
我对各种函数进行了一些速度测试,以返回所有当前子目录的完整路径。
tl;dr:
始终使用scandir:
list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]
奖励:scandir您也可以简单地使用f.name而不是f.path.
这(以及下面的所有其他函数)不会使用自然排序。这意味着结果将按如下方式排序:1, 10, 2。要获得自然排序 (1, 2, 10),请查看/sf/answers/3362121521/
结果:
scandir是:比walk快3 倍,比listdir(带过滤器)快 32 倍,比Pathlib快listdir35倍,比快36 倍,比 快37 倍(!)glob。
Scandir: 0.977
Walk: 3.011
Listdir (filter): 31.288
Pathlib: 34.075
Listdir: 35.501
Glob: 36.277
Run Code Online (Sandbox Code Playgroud)
使用 W7x64、Python 3.8.1 进行测试。包含 440 个子文件夹的文件夹。
如果您想知道是否listdir可以通过不执行 os.path.join() 两次来加快速度,是的,但是差异基本上不存在。
代码:
import os
import pathlib
import timeit
import glob
path = r"<example_path>"
def a():
list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]
# print(len(list_subfolders_with_paths))
def b():
list_subfolders_with_paths = [os.path.join(path, f) for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))]
# print(len(list_subfolders_with_paths))
def c():
list_subfolders_with_paths = []
for root, dirs, files in os.walk(path):
for dir in dirs:
list_subfolders_with_paths.append( os.path.join(root, dir) )
break
# print(len(list_subfolders_with_paths))
def d():
list_subfolders_with_paths = glob.glob(path + '/*/')
# print(len(list_subfolders_with_paths))
def e():
list_subfolders_with_paths = list(filter(os.path.isdir, [os.path.join(path, f) for f in os.listdir(path)]))
# print(len(list(list_subfolders_with_paths)))
def f():
p = pathlib.Path(path)
list_subfolders_with_paths = [x for x in p.iterdir() if x.is_dir()]
# print(len(list_subfolders_with_paths))
print(f"Scandir: {timeit.timeit(a, number=1000):.3f}")
print(f"Listdir: {timeit.timeit(b, number=1000):.3f}")
print(f"Walk: {timeit.timeit(c, number=1000):.3f}")
print(f"Glob: {timeit.timeit(d, number=1000):.3f}")
print(f"Listdir (filter): {timeit.timeit(e, number=1000):.3f}")
print(f"Pathlib: {timeit.timeit(f, number=1000):.3f}")
Run Code Online (Sandbox Code Playgroud)
ari*_*ari 72
为什么没有人提到glob?glob让你使用Unix风格的路径名扩展,并且几乎所有需要找到多个路径名的东西都可以使用.这很容易:
from glob import glob
paths = glob('*/')
Run Code Online (Sandbox Code Playgroud)
请注意,glob将返回带有最终斜杠的目录(如unix所示),而大多数path基于解决方案的操作将省略最终斜杠.
Gen*_*wen 31
选中" 获取当前目录中所有子目录的列表 ".
这是一个Python 3版本:
import os
dir_list = next(os.walk('.'))[1]
print(dir_list)
Run Code Online (Sandbox Code Playgroud)
Mil*_*lan 19
import os, os.path
Run Code Online (Sandbox Code Playgroud)
要在目录中获取(完整路径)直接子目录:
def SubDirPath (d):
return filter(os.path.isdir, [os.path.join(d,f) for f in os.listdir(d)])
Run Code Online (Sandbox Code Playgroud)
要获取最新(最新)子目录:
def LatestDirectory (d):
return max(SubDirPath(d), key=os.path.getmtime)
Run Code Online (Sandbox Code Playgroud)
Sua*_*ris 10
这种方法很好地一气呵成.
from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]
Run Code Online (Sandbox Code Playgroud)
使用Twisted的FilePath模块:
from twisted.python.filepath import FilePath
def subdirs(pathObj):
for subpath in pathObj.walk():
if subpath.isdir():
yield subpath
if __name__ == '__main__':
for subdir in subdirs(FilePath(".")):
print "Subdirectory:", subdir
Run Code Online (Sandbox Code Playgroud)
由于一些评论者已经问过使用Twisted库的优势是什么,我将在这里略微超出原来的问题.
在分支中有一些改进的文档解释了FilePath的优点; 你可能想读这个.
更具体地说,在此示例中:与标准库版本不同,此函数可以在没有导入的情况下实现."subdirs"函数是完全通用的,因为它只对其参数进行操作.为了使用标准库复制和移动文件,您需要依赖于" open"内置," listdir",或许" isdir"或" os.walk"或" shutil.copy".也许" os.path.join"也是.更不用说你需要一个传递参数的字符串来识别实际文件.让我们看看将每个目录的"index.tpl"复制到"index.html"的完整实现:
def copyTemplates(topdir):
for subdir in subdirs(topdir):
tpl = subdir.child("index.tpl")
if tpl.exists():
tpl.copyTo(subdir.child("index.html"))
Run Code Online (Sandbox Code Playgroud)
上面的"subdirs"函数可以在任何类似FilePath的对象上工作.除其他外,这意味着ZipPath对象.不幸的ZipPath是,它现在是只读的,但它可以扩展到支持写作.
您还可以传递自己的对象以进行测试.为了测试这里建议的os.path-using API,你必须使用导入的名称和隐式依赖项,并且通常执行黑魔法以使测试工作.使用FilePath,您可以执行以下操作:
class MyFakePath:
def child(self, name):
"Return an appropriate child object"
def walk(self):
"Return an iterable of MyFakePath objects"
def exists(self):
"Return true or false, as appropriate to the test"
def isdir(self):
"Return true or false, as appropriate to the test"
...
subdirs(MyFakePath(...))
Run Code Online (Sandbox Code Playgroud)