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

时间:2008-09-26 19:01:07

标签: 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']

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

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

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

19 个答案:

答案 0 :(得分:156)

os.walk

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

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

对于 Python< = 2.5 使用:

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

如何运作

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

答案 1 :(得分:96)

使用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']

答案 2 :(得分:42)

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

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

答案 3 :(得分:12)

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

答案 4 :(得分: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))]

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

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

答案 5 :(得分: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

os.listdir()的过滤速度要快一些。

答案 6 :(得分:6)

一种非常简单和优雅的方式是使用它:

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

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

答案 7 :(得分:5)

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

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

答案 8 :(得分:2)

在这里成为新手我还不能直接评论,但这里是一个小修正我想添加到ΤΖΩΤΖΙΟΥ's answer的以下部分:

  

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

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 :内部构造需要是一个列表而不是一个元组,因此应该如下所示:

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

否则会出现语法错误。

答案 9 :(得分:2)

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

from pathlib import Path

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

答案 10 :(得分:2)

使用列表理解

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

我认为这是最简单的方法

答案 11 :(得分:1)

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

答案 12 :(得分:1)

有关完整路径名的列表,我更喜欢这个版本,而不是solutions

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))]

答案 13 :(得分:1)

scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]

答案 14 :(得分:0)

您也可以使用 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 对象公开此信息,如果 操作系统在扫描目录时提供它。

答案 15 :(得分:0)

FWIW,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)

答案 16 :(得分:0)

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

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 []

答案 17 :(得分:0)

喜欢这样吗?

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

答案 18 :(得分:-1)

-- 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