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

fue*_*sjr 111 python filesystems

我希望能够只列出某个文件夹中的目录.这意味着我不希望列出文件名,也不想要其他子文件夹.

让我们看一个例子是否有帮助.在当前目录中,我们有:

>>> 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']
Run Code Online (Sandbox Code Playgroud)

但是,我不希望列出文件名.我也不想要像\ Lib\curses这样的子文件夹.基本上我想要的是以下内容:

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

但是,我想知道是否有更简单的方法来实现相同的结果.我得到的印象是,使用os.walk只返回顶级效率低效/太多.

Ale*_*try 175

os.walk

os.walknext项目功能一起使用:

next(os.walk('.'))[1]
Run Code Online (Sandbox Code Playgroud)

对于Python <= 2.5,请使用:

os.walk('.').next()[1]
Run Code Online (Sandbox Code Playgroud)

这是如何工作的

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

  • for python v3:next(os.walk('.')))[1] (38认同)
  • 关于这一点的更多描述是这是一个发电机,除非你告诉它,它不会走向其他目的地.所以.next()[1]在一行中做了所有列表推导所做的事情.我可能会做一些像`DIRNAMES = 1`然后`next()[DIRNAMES]`的东西,以便更容易理解未来的代码维护者. (14认同)
  • +1惊人的解决方案 要指定要浏览的目录,请使用:`os.walk(os.path.join(mypath,'.')).next()[1]` (3认同)

Tho*_*ers 106

使用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']
Run Code Online (Sandbox Code Playgroud)

  • 这需要大量的处理与非常简单的os.walk().next()[1] (13认同)

Col*_*sen 45

使用os.path.isdir过滤列表以检测目录.

filter(os.path.isdir, os.listdir(os.getcwd()))
Run Code Online (Sandbox Code Playgroud)

  • 这没用.我的猜测是`os.listdir`返回一个文件/文件夹名,传递给`os.path.isdir`,但后者需要一个完整的路径. (14认同)
  • 我认为这是迄今为止这些答案中可读性和简洁性的最佳组合. (4认同)
  • 这里的评论是 os.listdir 不返回绝对路径,因此 `filter(os.path.isdir, [os.path.join(base, f) for f in os.listdir(base)])` 解决了这个问题我。 (3认同)
  • filter比os.walk`timeit更快(os.walk(os.getcwd()).next()[1])``1000循环,最佳3:734μs每循环``timeit(filter(os.path) .isdir,os.listdir(os.getcwd())))``1000循环,最佳3:477μs每循环 (2认同)

Mar*_*ddy 14

directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
Run Code Online (Sandbox Code Playgroud)

  • 这可以缩短为filter(os.path.isdir,os.listdir(os.getcwd()) (4认同)
  • 有没有人有关于过滤器或列表理解是否更快的任何信息?否则它只是一个主观论点.这当然假设cwd中有1000万个目录,性能是个问题. (3认同)

tzo*_*zot 10

请注意,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))]
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢完整路径名,请使用此功能:

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


foz*_*foz 8

只是补充一点,使用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
Run Code Online (Sandbox Code Playgroud)

os.listdir()的过滤速度非常快.

  • 使用Python 3.5是获取目录内容的更快方法:https://www.python.org/dev/peps/pep-0471/ (2认同)

小智 8

使用列表理解,

[a for a in os.listdir() if os.path.isdir(a)]
Run Code Online (Sandbox Code Playgroud)

我认为这是最简单的方法


man*_*nty 6

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

 import os
 dir_list = os.walk('.').next()[1]
 print dir_list
Run Code Online (Sandbox Code Playgroud)

在您想要文件夹名称的同一文件夹中运行此脚本.它将仅提供您的直接文件夹名称(也没有文件夹的完整路径).


Tra*_*vis 5

这似乎也有效(至少在linux上):

import glob, os
glob.glob('*' + os.path.sep)
Run Code Online (Sandbox Code Playgroud)

  • 而不是glob.glob('\*'+ os.path.sep),如果os.path.isdir(dir),你可能想在glob.glob("\*")中编写[dir for dir] (4认同)
  • +1 表示“glob”。它可以为您节省大量代码,尤其是迭代,并且非常类似于 UNIX 终端使用 (`ls`) (2认同)

joe*_*lom 5

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

from pathlib import Path

p = Path('./')
[f for f in p.iterdir() if f.is_dir()]
Run Code Online (Sandbox Code Playgroud)


G M*_*G M 5

您还可以使用os.scandir

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

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

使用 scandir() 而不是 listdir() 可以显着提高还需要文件类型或文件属性信息的代码的性能,因为如果操作系统在扫描目录时提供此信息,则 os.DirEntry 对象会公开此信息。