关于python:获取当前目录中所有子目录的列表

Getting a list of all subdirectories in the current directory

有没有方法返回python中当前目录中所有子目录的列表?

我知道您可以对文件执行此操作,但我需要改为获取目录列表。


您的意思是直接子目录,还是树下的每个目录?

无论哪种方式,您都可以使用os.walk来执行此操作:

1
os.walk(directory)

将为每个子目录生成一个元组。3元组中的第一个条目是目录名,所以

1
[x[0] for x in os.walk(directory)]

应该递归地给出所有子目录。

注意,tuple中的第二个条目是第一个位置的条目的子目录列表,因此您可以使用它,但它不太可能为您节省太多。

但是,您可以使用它来为您提供直接子目录:

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

或者查看已经发布的其他解决方案,使用os.listdiros.path.isdir,包括"如何在python中获取所有直接子目录"中的解决方案。


1
2
3
4
5
import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d)
                    if os.path.isdir(os.path.join(d,o))]


你可以只用glob.glob

1
2
from glob import glob
glob("/path/to/directory/*/")

别忘了后面的/跟在*后面。


比上面的更好,因为您不需要几个os.path.join(),并且您将直接获得完整的路径(如果愿意的话),所以可以在python 3.5中这样做。+

1
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


如果需要查找子目录中所有子目录的递归解决方案,请按照前面的建议使用walk。

如果只需要当前目录的子目录,请将os.listdiros.path.isdir组合起来。


我更喜欢使用过滤器(https://docs.python.org/2/library/functions.html filter),但这只是一个品味问题。

1
2
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/)

1
2
3
4
5
6
7
8
9
10
11
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中获取子目录(和文件)的列表。

1
2
import os
os.listdir(path)  # list of subdirectories and files


只列出目录

1
2
3
4
print("
We are listing out only the directories in current directory -"
)
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)

只列出当前目录中的文件

1
2
3
4
files = filter(os.path.isfile, os.listdir(os.curdir))
print("
The following are the list of all files in the current directory -"
)
print(files)


由于我使用python 3.4和windows unc路径偶然发现了这个问题,下面是这个环境的一个变体:

1
2
3
4
5
6
7
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


谢谢你的提示,伙计们。我遇到了一个问题,软链接(无限递归)作为dirs返回。Softlinks?我们不希望有任何恶臭的软链接!所以…

这只呈现了dirs,而不是软链接:

1
2
3
4
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']


虽然这个问题很久以前就得到了解答。我建议使用pathlib模块,因为这是一种在Windows和Unix操作系统上工作的可靠方法。

因此,要获取特定目录(包括子目录)中的所有路径,请执行以下操作:

1
2
3
4
5
6
7
8
9
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

等。


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

1
2
3
4
5
6
7
8
9
10
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('**/'))

pathlib也可以通过pypi上的pathlib2模块在python 2.7上使用。


全径核算路径为...\\..\\..\\subfolder等:

1
2
3
import os, pprint
pprint.pprint([os.path.join(os.path.abspath(path), x[0]) \
    for x in os.walk(os.path.abspath(path))])


基于Eli Bendersky的解决方案,使用以下示例:

1
2
3
4
5
6
7
import os
test_directory = <your_directory>
for child in os.listdir(test_directory):
    test_path = os.path.join(test_directory, child)
    if os.path.isdir(test_path):
        print test_path
        # Do stuff to the directory"test_path"

其中,是要遍历的目录的路径。


下面是基于@blair conrad示例的几个简单函数-

1
2
3
4
5
6
7
8
9
import os

def get_subdirs(dir):
   "Get a list of immediate subdirectories"
    return next(os.walk(dir))[1]

def get_subfiles(dir):
   "Get a list of immediate subfiles"
    return next(os.walk(dir))[2]

这个答案似乎已经不存在了。

1
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]


我最近也遇到过类似的问题,我发现对于python 3.6(正如用户havlock添加的那样),最好的答案是使用os.scandir。由于似乎没有解决方案,我将添加自己的解决方案。首先,只列出根目录下直接子目录的非递归解决方案。

1
2
3
4
5
6
7
8
9
10
11
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

递归版本如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
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。有关entry对象的更多详细信息,请参阅os.direntry。


ipython中的复制粘贴友好:

1
2
3
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))

print(folders)输出:

1
['folderA', 'folderB']


os.listdir()上使用过滤函数os.path.isdir。像这样的东西


如果您只想要最上面的列表文件夹,请使用listdir,因为walk需要花费太多时间。