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


132

我希望仅列出某个文件夹内的目录。这意味着我既不需要列出文件名,也不需要其他子文件夹。

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

>>> 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返回顶级是无效的/太多了。

Answers:


125

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

17
与非常简单的os.walk()。next()[1]相比,这需要大量的处理
Phyo Arkar Lwin 2012年

203

步行

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

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

对于Python <= 2.5,请使用:

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

如何运作

os.walk是一个生成器,调用next将以3元组(目录路径,目录名,文件名)的形式获取第一个结果。因此,[1]索引仅返回dirnames该元组的。


14
关于此的更多描述是,这是一个生成器,除非您告诉它,否则它不会绕过其他目录。因此.next()[1]可以在一行代码中完成所有列表推导操作。我可能会做类似的事情DIRNAMES=1,然后next()[DIRNAMES]让以后的代码维护人员更容易理解。
boatcoder

3
+1了不起的解决方案。要指定要浏览的目录,请使用:os.walk( os.path.join(mypath,'.')).next()[1]
Daniel Reis 2012年

42
对于python v3:next(os.walk('。'))[1]
Andre Soares 2012年

如果您打算做更多的事情,那么文本处理;即在实际文件夹中进行处理,则可能需要完整路径:sorted( [os.path.join(os.getcwd(), item) for item in os.walk(os.curdir).next()[1]] )
DevPlayer

52

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

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

5
我认为这是迄今为止所有这些答案中可读性和简洁性的最佳组合。
vergenzt 2012年

20
这没用。我的猜测是os.listdir返回文件/文件夹名称,并将其传递给os.path.isdir,但后者需要完整路径。
丹尼尔·里斯

3
过滤器比os.walk快 timeit(os.walk(os.getcwd()).next()[1]) 1000 loops, best of 3: 734 µs per loop timeit(filter(os.path.isdir, os.listdir(os.getcwd()))) 1000 loops, best of 3: 477 µs per loop
-B.Kocis,

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

4
可以将其缩短为过滤器(os.path.isdir,os.listdir(os.getcwd())
约翰·米利肯

3
是否有人对筛选器或列表理解是否更快有任何信息?否则,它只是一个主观论点。当然,这假定cwd中有1000万个目录,而性能是一个问题。
Mark Roddy

12

请注意,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)
    ]

9

这似乎也起作用(至少在Linux上):

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

1
为+1 glob。它可以节省大量代码,尤其是迭代,并且非常类似于UNIX终端用法(ls
Gerard

5
而不是glob.glob('*'+ os.path.sep),您可能想要编写[如果os.path.isdir(dir)是glob.glob(“ *”)中dir的目录]
Eamonn MR

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()的过滤非常快。


2
使用Python 3.5是一种获取目录内容的更快方法:python.org/dev/peps/pep-0471
foz,

1
pep-0471- scandir程序包-很高兴在python 2.6及更高版本上作为PyPI上的可安装程序包提供。它提供了替代品,os.walk而且os.listdir速度更快。
foz

6

一种非常简单而优雅的方法是使用此方法:

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

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


6

使用列表理解

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

我认为这是最简单的方法


2

作为一个新手,我还不能直接发表评论,但这是我想补充到ΤζΩΤζΙΟΥ的以下部分的一个小更正:

如果您希望使用完整路径名,请使用以下功能:

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

否则会出现语法错误。


我知道已经有一段时间了,但是第一个例子确实帮助了我。
Inbar Rose

1
您收到语法错误,因为您的版本不支持生成器表达式。这些是在Python 2.4中引入的,而列表推导自Python 2.0起就可以使用。
2013年

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


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



0

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

from pathlib import Path

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

-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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.