Answers:
您是指直接子目录,还是树下的每个目录?
无论哪种方式,您都可以使用os.walk
以下方法:
os.walk(directory)
将为每个子目录生成一个元组。该三元组中的第一个条目是目录名称,因此
[x[0] for x in os.walk(directory)]
应该递归地给你所有的子目录。
请注意,该元组中的第二个条目是该条目的子目录列表的第一个位置,因此您可以改用它,但是不太可能为您节省很多。
但是,您可以使用它来为您提供直接的子目录:
next(os.walk('.'))[1]
或者使用os.listdir
和查看已经发布的其他解决方案os.path.isdir
,包括“ 如何在Python中获取所有直接子目录 ”中的解决方案。
os.walk('.').next()[1]
或使用os.walk('.').__next__()[1]
。相反,请使用内置函数next()
,该函数在Python 2(请参阅doc)和Python 3(请参阅doc)中都可用。例如:next(os.walk('.'))[1]
。
os.walk('.').next()[1]
直接使用不好?
os.walk
与os.listdir
+ os.path.isdir
解决方案:我只是测试的10,000子目录(以百万计的在下面的层次结构中的文件)的目录和性能上的差异可以忽略不计。os.walk
:“ 10个循环,每个循环最好3:44.6毫秒”和os.listdir
+ os.path.isdir
:“ 10个循环,每个循环最好3:45.1毫秒”
import os
d = '.'
[os.path.join(d, o) for o in os.listdir(d)
if os.path.isdir(os.path.join(d,o))]
os.path.join
o
isdir(0)
os.path.join
再次拨打电话,您可以先加入,然后使用os.path.isdir
以下方法过滤列表: filter(os.path.isdir, [os.path.join(d, o) for o in os.listdir(d)])
你可以用 glob.glob
from glob import glob
glob("/path/to/directory/*/")
别忘了/
之后的尾随*
。
/
名字的尾随
/
是文件夹分隔符,请执行以下操作:glob(os.path.join(path_to_directory, "*", ""))
recursive=True
比上面的要好得多,因为您不需要几个os.path.join(),并且可以直接获取完整路径(如果需要),因此可以在Python 3.5及更高版本中执行此操作。
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
这将提供到子目录的完整路径。如果只希望使用子目录的名称,f.name
而不是f.path
https://docs.python.org/3/library/os.html#os.scandir
OT:如果您需要递归所有子文件夹和/或所有文件,请看一下此功能,它比os.walk
&快,glob
并且将返回所有子文件夹以及这些(子)子文件夹中的所有文件的列表:https://stackoverflow.com/a/59803793/2441026
如果您只需要递归所有子文件夹:
def fast_scandir(dirname):
subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
for dirname in list(subfolders):
subfolders.extend(fast_scandir(dirname))
return subfolders
返回所有子文件夹及其完整路径的列表。这又比os.walk
和快得多glob
。
所有功能分析
tl; dr:
-如果要获取文件夹使用的所有直接子目录os.scandir
。
-如果要获取所有子目录,甚至嵌套的子目录,请使用os.walk
或-稍微快一点- fast_scandir
上面的函数。
-从来不使用os.walk
只顶级子目录,因为它可以是数百倍慢于(!) os.scandir
。
os.walk
将是基本文件夹。因此,您将不会仅获得子目录。您可以使用fu.pop(0)
将其删除。结果:
os.scandir took 1 ms. Found dirs: 439
os.walk took 463 ms. Found dirs: 441 -> it found the nested one + base folder.
glob.glob took 20 ms. Found dirs: 439
pathlib.iterdir took 18 ms. Found dirs: 439
os.listdir took 18 ms. Found dirs: 439
已在W7x64,Python 3.8.1中测试。
# -*- coding: utf-8 -*-
# Python 3
import time
import os
from glob import glob
from pathlib import Path
directory = r"<insert_folder>"
RUNS = 1
def run_os_walk():
a = time.time_ns()
for i in range(RUNS):
fu = [x[0] for x in os.walk(directory)]
print(f"os.walk\t\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_glob():
a = time.time_ns()
for i in range(RUNS):
fu = glob(directory + "/*/")
print(f"glob.glob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_pathlib_iterdir():
a = time.time_ns()
for i in range(RUNS):
dirname = Path(directory)
fu = [f for f in dirname.iterdir() if f.is_dir()]
print(f"pathlib.iterdir\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_os_listdir():
a = time.time_ns()
for i in range(RUNS):
dirname = Path(directory)
fu = [os.path.join(directory, o) for o in os.listdir(directory) if os.path.isdir(os.path.join(directory, o))]
print(f"os.listdir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_os_scandir():
a = time.time_ns()
for i in range(RUNS):
fu = [f.path for f in os.scandir(directory) if f.is_dir()]
print(f"os.scandir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.\tFound dirs: {len(fu)}")
if __name__ == '__main__':
run_os_scandir()
run_os_walk()
run_glob()
run_pathlib_iterdir()
run_os_listdir()
我更喜欢使用过滤器(https://docs.python.org/2/library/functions.html#filter),但这只是一个问题。
d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
使用python-os-walk实现了这一点。(http://www.pythonforbeginners.com/code-snippets-source-code/python-os-walk/)
import os
print("root prints out directories only from what you specified")
print("dirs prints out sub-directories from root")
print("files prints out all files from root and directories")
print("*" * 20)
for root, dirs, files in os.walk("/var/log"):
print(root)
print(dirs)
print(files)
您可以使用os.listdir(path)获取Python 2.7中的子目录(和文件)列表
import os
os.listdir(path) # list of subdirectories and files
os.listdir
列出目录的内容,包括文件。
print("\nWe are listing out only the directories in current directory -")
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)
files = filter(os.path.isfile, os.listdir(os.curdir))
print("\nThe following are the list of all files in the current directory -")
print(files)
蟒3.4引入的pathlib
模块到标准库,它提供了一个面向对象的方法来处理的文件系统的路径:
from pathlib import Path
p = Path('./')
# List comprehension
[f for f in p.iterdir() if f.is_dir()]
# The trailing slash to glob indicated directories
# This will also include the current directory '.'
list(p.glob('**/'))
也可以通过PyPi上的pathlib2模块在 Python 2.7 上使用Pathlib。
for f in filter(Path.is_dir, p.iterdir()):
由于我使用Python 3.4和Windows UNC路径偶然发现了此问题,因此以下是此环境的变体:
from pathlib import WindowsPath
def SubDirPath (d):
return [f for f in d.iterdir() if f.is_dir()]
subdirs = SubDirPath(WindowsPath(r'\\file01.acme.local\home$'))
print(subdirs)
Pathlib是Python 3.4中的新增功能,它使在不同操作系统下使用路径变得更加容易:https ://docs.python.org/3.4/library/pathlib.html
尽管很久以前就回答了这个问题。我想建议使用该pathlib
模块,因为这是在Windows和Unix OS上工作的可靠方法。
因此,要获取特定目录(包括子目录)中的所有路径:
from pathlib import Path
paths = list(Path('myhomefolder', 'folder').glob('**/*.txt'))
# all sorts of operations
file = paths[0]
file.name
file.stem
file.parent
file.suffix
等等
复制粘贴友好ipython
:
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
来自的输出print(folders)
:
['folderA', 'folderB']
x
是创建者列表中的项目,os.listdir(d)
因为listdir
它将返回他使用filter
命令os.path.isdir
用于从列表中过滤掉任何文件的文件和文件夹。
这就是我的方法。
import os
for x in os.listdir(os.getcwd()):
if os.path.isdir(x):
print(x)
这个答案似乎还不存在。
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]
我最近有一个类似的问题,我发现python 3.6(作为用户havlock添加)的最佳答案是使用os.scandir
。由于似乎没有使用它的解决方案,因此我将添加自己的解决方案。首先,一种非递归解决方案,仅列出直接位于根目录下的子目录。
def get_dirlist(rootdir):
dirlist = []
with os.scandir(rootdir) as rit:
for entry in rit:
if not entry.name.startswith('.') and entry.is_dir():
dirlist.append(entry.path)
dirlist.sort() # Optional, in case you want sorted directory names
return dirlist
递归版本如下所示:
def get_dirlist(rootdir):
dirlist = []
with os.scandir(rootdir) as rit:
for entry in rit:
if not entry.name.startswith('.') and entry.is_dir():
dirlist.append(entry.path)
dirlist += get_dirlist(entry.path)
dirlist.sort() # Optional, in case you want sorted directory names
return dirlist
请记住,这entry.path
将使用子目录的绝对路径。如果只需要文件夹名称,则可以entry.name
改用。有关该对象的更多详细信息,请参考os.DirEntryentry
。
返回给定文件路径中所有子目录的列表的函数。将搜索整个文件树。
import os
def get_sub_directory_paths(start_directory, sub_directories):
"""
This method iterates through all subdirectory paths of a given
directory to collect all directory paths.
:param start_directory: The starting directory path.
:param sub_directories: A List that all subdirectory paths will be
stored to.
:return: A List of all sub-directory paths.
"""
for item in os.listdir(start_directory):
full_path = os.path.join(start_directory, item)
if os.path.isdir(full_path):
sub_directories.append(full_path)
# Recursive call to search through all subdirectories.
get_sub_directory_paths(full_path, sub_directories)
return sub_directories
我们可以使用os.walk()获取所有文件夹的列表
import os
path = os.getcwd()
pathObject = os.walk(path)
这个pathObject是一个对象,我们可以通过
arr = [x for x in pathObject]
arr is of type [('current directory', [array of folder in current directory], [files in current directory]),('subdirectory', [array of folder in subdirectory], [files in subdirectory]) ....]
我们可以通过遍历arr并打印中间数组来获取所有子目录的列表
for i in arr:
for j in i[1]:
print(j)
这将打印所有子目录。
要获取所有文件:
for i in arr:
for j in i[2]:
print(i[0] + "/" + j)
具有给定父级的该函数以递归方式directory
遍历其所有函数directories
以及prints
在filenames
其中找到的所有函数。太有用了。
import os
def printDirectoryFiles(directory):
for filename in os.listdir(directory):
full_path=os.path.join(directory, filename)
if not os.path.isdir(full_path):
print( full_path + "\n")
def checkFolders(directory):
dir_list = next(os.walk(directory))[1]
#print(dir_list)
for dir in dir_list:
print(dir)
checkFolders(directory +"/"+ dir)
printDirectoryFiles(directory)
main_dir="C:/Users/S0082448/Desktop/carpeta1"
checkFolders(main_dir)
input("Press enter to exit ;")