我正在尝试编写一个简单的Python脚本,它将所有子目录中的index.tpl复制到index.html(有一些例外)。
通过尝试获取子目录列表,我陷入了困境。
我对各种功能进行了 速度测试 ,以将 完整路径 返回到所有当前子目录。
tl; dr: 始终使用scandir:
scandir
list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]
奖励:使用,scandir您也可以只使用f.name而不是来获取文件夹名称f.path。
f.name
f.path
该函数(以及下面的所有其他函数)将不会使用 自然排序 。这意味着将对结果进行如下排序:1、10、2。要进行自然排序(1、2、10),请查看http://codingdict.com/questions/169984
结果 : scandir是:比walk快3倍,比listdir(带过滤器)快32倍,比Pathlib快listdir35倍,快36倍,比快37倍(!)glob。
walk
listdir
Pathlib
glob
Scandir: 0.977 Walk: 3.011 Listdir (filter): 31.288 Pathlib: 34.075 Listdir: 35.501 Glob: 36.277
已在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}")