有没有办法在Python中返回当前目录中所有子目录的列表?
我知道可以获取文件列表,但我需要获取目录列表。
有没有办法在Python中返回当前目录中所有子目录的列表?
我知道可以获取文件列表,但我需要获取目录列表。
dirs_rglob = [x for x in folder.rglob('*') if x.is_dir()]
dirs_walk = [x[0] for x in os.walk(folder)]
dirs_custom = fast_scandir(folder)
其中fast_scandir()
是由用户136036建议的自定义函数,请参见下面的代码。我使用以下Python代码测试了性能:
from pathlib import Path
from os import walk,scandir
from time import monotonic
#user136036 custom code:
def fast_scandir(dirname):
subfolders= [f.path for f in scandir(dirname) if f.is_dir()]
for dirname in list(subfolders):
subfolders.extend(fast_scandir(dirname))
return subfolders
folder = Path('c:/xampp/htdocs/fonts') # Insert your path here
msg = 'Using {}, seconds: {}, number of folders: {}.\n'
start = monotonic()
dirs_rglob = [x for x in folder.rglob('*') if x.is_dir()]
print(msg.format('Path.rglob', monotonic() - start, len(dirs_rglob)))
start = monotonic()
dirs_walk = [x[0] for x in walk(folder)]
print(msg.format('os.walk', monotonic() - start, len(dirs_walk)))
start = monotonic()
dirs_custom = fast_scandir(folder)
print(msg.format('fast_scandir', monotonic() - start, len(dirs_custom)))
正如用户136036所述,他的自定义方法是最快的,但与os.walk(folder)
相比并不多,而folder.rglob('*')
真的非常慢。由于自定义方法并没有快多少,我使用os.walk(folder)
,因为后者对于系统文件夹或回收站在Windows操作系统中没有问题。
如果您只需要立即文件夹的列表,可以使用
dirs_iter = [ f for f in folder.iterdir() if f.is_dir()]
dirs_scan = [ f.path for f in os.scandir(folder) if f.is_dir()]
经过测试,两种方法的运行时间都非常短,其中folder.iterdir()
方法有时略微更快。
总之:对于整个子目录树,请使用os.walk(folder)
,对于直接子目录,请使用folder.iterdir()
或os.scandir(folder)
。
import os
import json
class GetDirectoryList():
def __init__(self, path):
self.main_path = path
self.absolute_path = []
self.relative_path = []
def get_files_and_folders(self, resp, path):
all = os.listdir(path)
resp["files"] = []
for file_folder in all:
if file_folder != "." and file_folder != "..":
if os.path.isdir(path + "/" + file_folder):
resp[file_folder] = {}
self.get_files_and_folders(resp=resp[file_folder], path= path + "/" + file_folder)
else:
resp["files"].append(file_folder)
self.absolute_path.append(path.replace(self.main_path + "/", "") + "/" + file_folder)
self.relative_path.append(path + "/" + file_folder)
return resp, self.relative_path, self.absolute_path
@property
def get_all_files_folder(self):
self.resp = {self.main_path: {}}
all = self.get_files_and_folders(self.resp[self.main_path], self.main_path)
return all
if __name__ == '__main__':
mylib = GetDirectoryList(path="sample_folder")
file_list = mylib.get_all_files_folder
print (json.dumps(file_list))
而示例目录看起来像这样
sample_folder/
lib_a/
lib_c/
lib_e/
__init__.py
a.txt
__init__.py
b.txt
c.txt
lib_d/
__init__.py
__init__.py
d.txt
lib_b/
__init__.py
e.txt
__init__.py
得到的结果
[
{
"files": [
"__init__.py"
],
"lib_b": {
"files": [
"__init__.py",
"e.txt"
]
},
"lib_a": {
"files": [
"__init__.py",
"d.txt"
],
"lib_c": {
"files": [
"__init__.py",
"c.txt",
"b.txt"
],
"lib_e": {
"files": [
"__init__.py",
"a.txt"
]
}
},
"lib_d": {
"files": [
"__init__.py"
]
}
}
},
[
"sample_folder/lib_b/__init__.py",
"sample_folder/lib_b/e.txt",
"sample_folder/__init__.py",
"sample_folder/lib_a/lib_c/lib_e/__init__.py",
"sample_folder/lib_a/lib_c/lib_e/a.txt",
"sample_folder/lib_a/lib_c/__init__.py",
"sample_folder/lib_a/lib_c/c.txt",
"sample_folder/lib_a/lib_c/b.txt",
"sample_folder/lib_a/lib_d/__init__.py",
"sample_folder/lib_a/__init__.py",
"sample_folder/lib_a/d.txt"
],
[
"lib_b/__init__.py",
"lib_b/e.txt",
"sample_folder/__init__.py",
"lib_a/lib_c/lib_e/__init__.py",
"lib_a/lib_c/lib_e/a.txt",
"lib_a/lib_c/__init__.py",
"lib_a/lib_c/c.txt",
"lib_a/lib_c/b.txt",
"lib_a/lib_d/__init__.py",
"lib_a/__init__.py",
"lib_a/d.txt"
]
]
~\AppData\Local\Temp\ipykernel_12328\702766901.py in ()
32 #mylib = GetDirectoryList(path="sample_folder")
33 mylib = GetDirectoryList(os.getcwd())
---> 34 file_list = mylib.get_all_files_folder
35 print (json.dumps(file_list))``` |
- Rich Lysakowski PhD这是一个简单的递归解决方案
import os
def fn(dir=r"C:\Users\aryan\Downloads\opendatakit"): # 1.Get file names from directory
file_list = os.listdir(dir)
res = []
# print(file_list)
for file in file_list:
if os.path.isfile(os.path.join(dir, file)):
res.append(file)
else:
result = fn(os.path.join(dir, file))
if result:
res.extend(fn(os.path.join(dir, file)))
return res
res = fn()
print(res)
print(len(res))
import os
path = "test/"
files = [x[0] + "/" + y for x in os.walk(path) if len(x[-1]) > 0 for y in x[-1]]
这应该可以工作,因为它还创建了一个目录树;
import os
import pathlib
def tree(directory):
print(f'+ {directory}')
print("There are " + str(len(os.listdir(os.getcwd()))) + \
" folders in this directory;")
for path in sorted(directory.glob('*')):
depth = len(path.relative_to(directory).parts)
spacer = ' ' * depth
print(f'{spacer}+ {path.name}')
使用 pathlib
库,应该列出文件夹中的所有目录。 path.relative_to(directory).parts
获取相对于当前工作目录的元素。
[f for f in data_path.iterdir() if f.is_dir()]
。这将返回文件夹名称作为字符串,还会自动排除.
和..
,非常感谢。另外,glob.glob解决方案也很有价值:glob.glob("/path/to/directory/*/")
。 - Charlie Parker