如何在 Python 中只列出顶级目录?

我希望只能列出某个文件夹中的目录。 这意味着我不希望列出文件名,也不希望额外的子文件夹。

让我们看看一个例子是否有帮助。在工作目录中我们有:

>>> os.listdir(os.getcwd())
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'mod_p
ython-wininst.log', 'NEWS.txt', 'pymssql-wininst.log', 'python.exe', 'pythonw.ex
e', 'README.txt', 'Removemod_python.exe', 'Removepymssql.exe', 'Scripts', 'tcl',
'Tools', 'w9xpopen.exe']

但是,我不希望列出文件名。我也不希望子文件夹,如 Lib 诅咒。基本上,我想要的工作如下:

>>> for root, dirnames, filenames in os.walk('.'):
...     print dirnames
...     break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']

然而,我想知道是否有一种更简单的方法来达到同样的结果。我得到的印象是,使用 os.walk 只返回顶层是低效的/太多了。

224000 次浏览
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]

像这样?

>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]
[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]

使用 os.path.isdir ()筛选结果(并使用 os.path.join ()获取真正的路径) :

>>> [ name for name in os.listdir(thedir) if os.path.isdir(os.path.join(thedir, name)) ]
['ctypes', 'distutils', 'encodings', 'lib-tk', 'config', 'idlelib', 'xml', 'bsddb', 'hotshot', 'logging', 'doc', 'test', 'compiler', 'curses', 'site-packages', 'email', 'sqlite3', 'lib-dynload', 'wsgiref', 'plat-linux2', 'plat-mac']

使用 os.path.isdir 筛选列表以检测目录。

filter(os.path.isdir, os.listdir(os.getcwd()))

请注意,与其执行 os.listdir(os.getcwd()),不如执行 os.listdir(os.path.curdir)。少一个函数调用,它就具有可移植性。

因此,要完成这个问题的答案,需要获得一个文件夹中的目录列表:

def listdirs(folder):
return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

如果你喜欢完整的路径名,那么使用这个函数:

def listdirs(folder):
return [
d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
if os.path.isdir(d)
]

Os. 走

使用具有 next项目功能的 os.walk:

next(os.walk('.'))[1]

用于 Python < = 2.5:

os.walk('.').next()[1]

这是怎么回事

os.walk是一个生成器,调用 next将以3个元组(dirpath、 dirname、 filename)的形式获得第一个结果。因此,[1]索引只返回该元组中的 dirnames

在这里作为一个新手我还不能直接评论,但这里有一个小的更正,我想添加到 Something ΩD? ? ? ? ? ? ? ? ? 的以下部分:

如果你喜欢完整的路径名,那么使用这个函数:

def listdirs(folder):
return [
d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
if os.path.isdir(d)
]

对于那些仍然使用 python < 2.4 的用户: 内部结构需要是一个 list 而不是 tuple,因此应该是这样的:

def listdirs(folder):
return [
d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
if os.path.isdir(d)
]

否则就会出现语法错误。

只是要补充一点,使用 os.listdir ()并不是 “需要大量处理与非常简单的 os.walk () . next ()[1]”。这是因为 os.walk ()在内部使用 os.listdir ()。事实上,如果你把它们放在一起测试:

>>>> import timeit
>>>> timeit.timeit("os.walk('.').next()[1]", "import os", number=10000)
1.1215229034423828
>>>> timeit.timeit("[ name for name in os.listdir('.') if os.path.isdir(os.path.join('.', name)) ]", "import os", number=10000)
1.0592019557952881

对 os.listdir ()的过滤稍微快一些。

对于完整路径名的列表,我更喜欢这个版本,而不是另一个 解决方案:

def listdirs(dir):
return [os.path.join(os.path.join(dir, x)) for x in os.listdir(dir)
if os.path.isdir(os.path.join(dir, x))]

一种非常简单和优雅的方法是这样使用:

 import os
dir_list = os.walk('.').next()[1]
print dir_list

在需要文件夹名称的同一文件夹中运行此脚本。它将只给出直接文件夹名称(也没有文件夹的完整路径)。

这似乎也行得通(至少在 Linux 上) :

import glob, os
glob.glob('*' + os.path.sep)

一个更安全的选项,当没有目录时不会失败。

def listdirs(folder):
if os.path.exists(folder):
return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
else:
return []
scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]
-- This will exclude files and traverse through 1 level of sub folders in the root


def list_files(dir):
List = []
filterstr = ' '
for root, dirs, files in os.walk(dir, topdown = True):
#r.append(root)
if (root == dir):
pass
elif filterstr in root:
#filterstr = ' '
pass
else:
filterstr = root
#print(root)
for name in files:
print(root)
print(dirs)
List.append(os.path.join(root,name))
#print(os.path.join(root,name),"\n")
print(List,"\n")


return List

用列表内涵

[a for a in os.listdir() if os.path.isdir(a)]

我认为这是最简单的方法

Python 3.4将 pathlib模块引入到标准库中,它提供了一种面向对象的方法来处理文件系统路径:

from pathlib import Path


p = Path('./')
[f for f in p.iterdir() if f.is_dir()]

第四,os.walk方法的速度几乎是列表内涵和过滤方法的10倍:

In [30]: %timeit [d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
1.23 ms ± 97.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)


In [31]: %timeit list(filter(os.path.isdir, os.listdir(os.getcwd())))
1.13 ms ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)


In [32]: %timeit next(os.walk(os.getcwd()))[1]
132 µs ± 9.34 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

你也可以使用 os.scandir:

with os.scandir(os.getcwd()) as mydir:
dirs = [i.name for i in mydir if i.is_dir()]

如果需要完整路径,可以使用 i.path

使用 Scandir ()而不是 listdir ()可以显著增加 还需要文件类型或文件属性的代码的性能 信息,因为 os.DirEntry 对象在以下情况下公开此信息 操作系统在扫描目录时提供它。

使用 glob的2021年答案:

import glob, os


p = "/some/path/"
for d in glob.glob(p + "*" + os.path.sep):
print(d)

Pathlib. Path.iter _ dir中使用 python 3.x

$ mkdir tmpdir
$ mkdir -p tmpdir/a/b/c
$ mkdir -p tmpdir/x/y/z


$ touch tmpdir/a/b/c/abc.txt
$ touch tmpdir/a/b/ab.txt
$ touch tmpdir/a/a.txt


$ python --version
Python 3.7.12
>>> from pathlib import Path
>>> tmpdir = Path("./tmpdir")
>>> [d for d in tmpdir.iterdir() if d.is_dir]
[PosixPath('tmpdir/x'), PosixPath('tmpdir/a')]
>>> sorted(d for d in tmpdir.iterdir() if d.is_dir)
[PosixPath('tmpdir/a'), PosixPath('tmpdir/x')]