如何在Python中获取所有直接子目录
我正在尝试写一个简单的Python脚本,这个脚本会把一个叫做index.tpl的文件复制到所有子目录下,命名为index.html(不过有几个例外)。
我现在遇到麻烦了,因为我在获取子目录的列表时卡住了。
17 个回答
为什么没有人提到 glob
呢? glob
这个工具可以让你用类似Unix系统的路径方式来查找文件,它几乎是我用来寻找多个路径名的首选方法。使用起来非常简单:
from glob import glob
paths = glob('*/')
需要注意的是,glob
会返回带有最后一个斜杠的目录(就像Unix系统那样),而大多数基于 path
的解决方案则不会加上最后的斜杠。
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))]
当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。
我对几种函数进行了速度测试,目的是获取所有当前子目录的完整路径。
简单来说:
总是使用 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),可以查看这个链接:https://stackoverflow.com/a/48030307/2441026
测试结果:
scandir
的速度是 walk
的3倍,是 listdir
(带过滤)的32倍,是 Pathlib
的35倍,是 listdir
的36倍,甚至是 glob
的37倍!
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}")