获取当前目录中所有子目录的列表

Bra*_*eis 467 python directory subdirectory

有没有办法在Python中返回当前目录中所有子目录的列表?

我知道你可以用文件做到这一点,但我需要获取目录列表.

Bla*_*rad 536

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

无论哪种方式,您可以使用os.walk这样做:

os.walk(directory)
Run Code Online (Sandbox Code Playgroud)

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

[x[0] for x in os.walk(directory)]
Run Code Online (Sandbox Code Playgroud)

应该递归地给你所有的子目录.

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

但是,您可以使用它只是为了给您直接的子目录:

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

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

  • 不要使用``os.walk('.').next()[1]``或``os.walk('.').__ next __()[1]``直接.相反,使用内置函数``next()``,这在[Python 2(参见doc)](https://docs.python.org/2/library/functions.html#next)中都可用.和[Python 3(见文档)](https://docs.python.org/3/library/functions.html#next).例如:``next(os.walk('.'))[1]``. (18认同)
  • 对于任何关注`os.walk`和`os.listdir` +`os.path.isdir`解决方案之间性能差异的人:我刚刚测试了一个包含10,000个子目录的目录(下面的层次结构中有数百万个文件)和性能差异可以忽略不计.`os.walk`:"10循环,每循环最佳3:44.6毫秒"和`os.listdir` +`os.path.isdir`:"10循环,最佳3:每循环45.1毫秒" (12认同)
  • @wisbucky这是一个不好的做法,因为``iteraror .__ next __()``是一个内部方法,``iterator.next()``用法应该根据PEP转换为内置``next()`` -3114.参见2007年批准的[PEP-3114](https://www.python.org/dev/peps/pep-3114/). (7认同)
  • 我认为os.walk返回三元组(root,dirs,files).这意味着dirs有许多重复条目.是否有一种更有效的方法来通过目录进行递归? (6认同)
  • @kevinmicke 在网络驱动器上尝试这个性能测试,我想你会发现在这种情况下性能相当显着。 (5认同)
  • 这样一个干净又好的答案。谢谢。我不熟悉 next() 并认为此链接对处于类似情况的人有帮助:http://stackoverflow.com/questions/1733004/python-next-function (3认同)

gah*_*ooa 150

import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d) 
                    if os.path.isdir(os.path.join(d,o))]
Run Code Online (Sandbox Code Playgroud)

  • 看来帖子已经更新了上述两个问题的修复程序. (5认同)
  • 请注意,在这种方法中,如果不在"."上执行,则需要关注abspath问题. (4认同)
  • 如果你没有使用cwd('.'),这将无法工作,除非你在`o`上执行`os.path.join`以获得完整路径,否则`isdir(0)`总是会返回false (4认同)
  • 为了避免调用 `os.path.join` 两次,你可以先加入,然后使用 `os.path.isdir` 过滤列表: `filter(os.path.isdir, [os.path.join(d, o)对于 os.listdir(d)]) 中的 o (2认同)
  • 将 pathlib 与 `[f for f in data_path.iterdir() if f.is_dir()]` 或 glob 一起使用要简单得多,更容易阅读: `glob.glob("/path/to/directory/*/")` 。 (2认同)

小智 125

你可以使用 glob.glob

from glob import glob
glob("/path/to/directory/*/")
Run Code Online (Sandbox Code Playgroud)

不要忘了结尾/之后*.

  • 如果您不能假设`/`是文件夹分隔符,请执行以下操作:`glob(os.path.join(path_to_directory,"*",""))` (4认同)
  • 这不适用于子目录!要使用 glob,这里是完整的答案:[使用 Glob() 在 Python 中递归查找文件?](/sf/ask/153056781/ -Python) (4认同)
  • 要使 glob 递归,您只需添加以下参数 `recursive=True` (3认同)
  • 好的。简单的。只是,它在名称中留下了尾随的“/” (2认同)

use*_*036 72

比上面更好,因为你不需要几个os.path.join(),你将直接获得完整的路径(如果你愿意),你可以在Python 3.5+中执行此操作

subfolders = [f.path for f in os.scandir(folder) if f.is_dir() ]    
Run Code Online (Sandbox Code Playgroud)

这将给出子目录的完整路径.如果您只想使用子目录的名称f.name而不是f.path

https://docs.python.org/3/library/os.html#os.scandir

  • 如果您在问题中尽早提到您要替换您所描述的不同功能,那就太好了。不管怎样,你花时间做这件事令人印象深刻。好工作。我个人更喜欢使用单个库,所以我喜欢使用`pathlib`,如下所示`[f for f in p.iterdir() if f.is_dir()]`` (2认同)

Eli*_*sky 35

如果您需要一个可以找到子目录中所有子目录的递归解决方案,请使用之前建议的walk.

如果您只需要当前目录的子目录,请os.listdir与之结合使用os.path.isdir

  • 使用 `pathlib` 更简单:`[f for f in p.iterdir() if f.is_dir()]` (3认同)
  • @CharlieParker:这个答案早于“pathlib”几年。 (2认同)

sve*_*ten 27

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

d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
Run Code Online (Sandbox Code Playgroud)


Cha*_*ith 23

使用python-os-walk实现了这一点.(http://www.pythonforbeginners.com/code-snippets-source-code/python-os-walk/)

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


小智 20

您可以使用os.listdir(path)获取Python 2.7中的子目录(和文件)列表

import os
os.listdir(path)  # list of subdirectories and files
Run Code Online (Sandbox Code Playgroud)

  • 这也包括文件. (56认同)
  • 注意`os.listdir`会列出目录的内容,包括文件。 (3认同)
  • 名称令人困惑,因为“ dir”并不指向构成列表的对象,而是指向容器目录。请检查您的单行答案,对于初学者来说,选择它们非常诱人。 (2认同)

小智 13

仅列出目录

print("\nWe are listing out only the directories in current directory -")
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)
Run Code Online (Sandbox Code Playgroud)

列出当前目录中的文件

files = filter(os.path.isfile, os.listdir(os.curdir))
print("\nThe following are the list of all files in the current directory -")
print(files)
Run Code Online (Sandbox Code Playgroud)

  • 如果稍微修改该行,这将在当前目录之外工作: subdirs = filter(os.path.isdir, [os.path.join(dir,x) for x in os.listdir(dir)]) (5认同)
  • 没有在Mac OS上工作.我认为问题是os.listdir只返回目录的名称而不是完整路径,但是如果完整路径是目录,os.path.isdir只返回True. (2认同)

小智 11

由于我使用Python 3.4和Windows UNC路径偶然发现了这个问题,这里有一个适用于这种环境的变体:

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

Pathlib是Python 3.4中的新功能,可以更轻松地处理不同操作系统下的路径:https://docs.python.org/3.4/library/pathlib.html


API*_*API 10

虽然很久以前就回答了这个问题.我想建议使用该pathlib模块,因为这是一种在Windows和Unix OS上运行的强大方法.

因此,要获取特定目录中的所有路径,包括子目录:

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

等等


joe*_*lom 10

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

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

Pathlib也可以通过PyPi上的pathlib2模块在 Python 2.7 上使用.

  • 谢谢@CharlieParker!我用有关递归和使用尾部斜杠的详细信息更新了我的答案(包括注意到在将 `**` 与 pathlib 的 glob 一起使用时不需要尾部斜杠。关于,使用单个星号,这将非递归地匹配文件和目录。 (2认同)

Kur*_*rtB 9

谢谢提醒伙计.我遇到了一个软链接(无限递归)作为dirs返回的问题.软链接?我们不希望没有stinkin'软链接!所以...

这只是dirs,而不是softlinks:

>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
Run Code Online (Sandbox Code Playgroud)

  • python 中调用的 `[x[0] for x in inf]` 是什么,以便我可以查找它? (2认同)
  • @shinzou 这是一个列表理解。超级好用。还要查找字典理解。 (2认同)

Muj*_*que 9

我就是这样做的。

    import os
    for x in os.listdir(os.getcwd()):
        if os.path.isdir(x):
            print(x)
Run Code Online (Sandbox Code Playgroud)


Mii*_*ind 7

最简单的方法:

from pathlib import Path
from glob import glob

current_dir = Path.cwd()
all_sub_dir_paths = glob(str(current_dir) + '/*/') # returns list of sub directory paths

all_sub_dir_names = [Path(sub_dir).name for sub_dir in all_sub_dir_paths] 
Run Code Online (Sandbox Code Playgroud)


Bla*_*g23 6

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

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

<your_directory>您要遍历的目录的路径在哪里.


Bri*_*rns 6

以下是基于@Blair Conrad示例的几个简单函数 -

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


And*_*ber 6

复制粘贴友好ipython

import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
Run Code Online (Sandbox Code Playgroud)

来自的输出print(folders)

['folderA', 'folderB']
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下X是多少? (2认同)

Dev*_*yer 5

有了完整路径和占路为.,..,\\,..\\..\\subfolder,等:

import os, pprint
pprint.pprint([os.path.join(os.path.abspath(path), x[0]) \
    for x in os.walk(os.path.abspath(path))])
Run Code Online (Sandbox Code Playgroud)


And*_*ndy 5

这个答案似乎并不存在。

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

  • 如果您正在搜索除当前工作目录之外的任何内容,这将始终返回一个空列表,从技术上讲,这正是 OP 想要做的,但不太可重用。 (10认同)
  • 目录 = [ x for x in os.listdir(localDir) if os.path.isdir(localDir+x) (3认同)

Alb*_*o A 5

我最近有一个类似的问题,我发现 python 3.6 的最佳答案(如用户 havlock 添加的)是使用os.scandir. 由于似乎没有使用它的解决方案,因此我将添加自己的解决方案。首先,非递归解决方案,仅列出根目录正下方的子目录。

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

递归版本如下所示:

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

请记住,它entry.path使用子目录的绝对路径。如果您只需要文件夹名称,entry.name则可以使用。有关该对象的其他详细信息,请参阅os.DirEntryentry


vub*_*vub 5

使用操作系统步行

sub_folders = []
for dir, sub_dirs, files in os.walk(test_folder):
    sub_folders.extend(sub_dirs)
Run Code Online (Sandbox Code Playgroud)