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

2024-12-13 08:36:00
admin
原创
159
摘要:问题描述:有没有办法在 Python 中返回当前目录中所有子目录的列表?我知道您可以对文件执行此操作,但我需要获取目录列表。解决方案 1:您是指直接子目录,还是树下的每个目录?无论哪种方式,您都可以os.walk这样做:os.walk(directory) 将为每个子目录生成一个元组。三元组中的第一个条目是目...

问题描述:

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

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


解决方案 1:

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

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

os.walk(directory)

将为每个子目录生成一个元组。三元组中的第一个条目是目录名称,因此

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

应该以递归方式为您提供所有子目录。

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

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

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

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

解决方案 2:

比上面的好多了,因为你不需要几个 os.path.join() 并且你会直接得到完整的路径(如果你愿意的话),你可以在Python 3.5及更高版本中做到这一点。

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


稍微 OT:如果您需要递归所有子文件夹和/或递归所有文件,请查看此函数,它比os.walk&更快glob,并且将返回所有子文件夹以及这些(子)子文件夹内的所有文件的列表:https: //stackoverflow.com/a/59803793/2441026

如果您只想要递归的所有子文件夹

def fast_scandir(dirname):
    subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
    for dirname in list(subfolders):
        subfolders.extend(fast_scandir(dirname))
    return subfolders

返回所有子文件夹及其完整路径的列表。这再次比 快os.walk,而且快很多glob


全部功能的分析

tl;dr:

  • 如果您想获取文件夹的所有直接os.scandir子目录,请使用。

  • 如果您想获取所有子目录,甚至是嵌套子目录,请使用os.walk或 - 稍微快一点 -fast_scandir上面的函数。

  • 切勿os.walk仅用于顶级子目录,因为它可能比慢数百倍(!)os.scandir

  • 如果您运行下面的代码,请确保运行一次,以便您的操作系统访问该文件夹,丢弃结果并运行测试,否则结果将会被搞砸。

  • 您可能想要混合函数调用,但是我进行了测试,并且这并不重要。

  • 所有示例都将提供文件夹的完整路径。pathlib 示例为 (Windows)Path 对象。

  • 的第一个元素os.walk将是基本文件夹。因此,您将不会只获得子目录。您可以使用它fu.pop(0)来删除它。

  • 所有结果都不会使用自然排序。这意味着结果将按以下方式排序:1、10、2。要获得自然排序(1、2、10),请查看https://stackoverflow.com/a/48030307/2441026

结果

os.scandir      took   1 ms. Found dirs: 439
os.walk         took 463 ms. Found dirs: 441 -> it found the nested one + base folder.
glob.glob       took  20 ms. Found dirs: 439
pathlib.iterdir took  18 ms. Found dirs: 439
os.listdir      took  18 ms. Found dirs: 439

使用 W7x64、Python 3.8.1 进行测试。

# -*- coding: utf-8 -*-
# Python 3


import time
import os
from glob import glob
from pathlib import Path


directory = r"<insert_folder>"
RUNS = 1


def run_os_walk():
    a = time.time_ns()
    for i in range(RUNS):
        fu = [x[0] for x in os.walk(directory)]
    print(f"os.walk            took {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_glob():
    a = time.time_ns()
    for i in range(RUNS):
        fu = glob(directory + "/*/")
    print(f"glob.glob        took {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_pathlib_iterdir():
    a = time.time_ns()
    for i in range(RUNS):
        dirname = Path(directory)
        fu = [f for f in dirname.iterdir() if f.is_dir()]
    print(f"pathlib.iterdir    took {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_os_listdir():
    a = time.time_ns()
    for i in range(RUNS):
        dirname = Path(directory)
        fu = [os.path.join(directory, o) for o in os.listdir(directory) if os.path.isdir(os.path.join(directory, o))]
    print(f"os.listdir        took {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_os_scandir():
    a = time.time_ns()
    for i in range(RUNS):
        fu = [f.path for f in os.scandir(directory) if f.is_dir()]
    print(f"os.scandir        took {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.    Found dirs: {len(fu)}")


if __name__ == '__main__':
    run_os_scandir()
    run_os_walk()
    run_glob()
    run_pathlib_iterdir()
    run_os_listdir()

解决方案 3:

你可以使用glob.glob

from glob import glob
glob("/path/to/directory/*/", recursive = True)

不要忘记/后面的尾注*

解决方案 4:

import os

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

解决方案 5:

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

from pathlib import Path

p = Path('./')

# All subdirectories in the current directory, not recursive.
[f for f in p.iterdir() if f.is_dir()]

要递归列出所有子目录,可以将路径通配符与模式一起使用**

# This will also include the current directory '.'
list(p.glob('**'))

请注意,单个*作为 glob 模式将非递归地包含文件和目录。要仅获取目录,/可以附加尾随,但这仅在直接使用 glob 库时有效,在通过 pathlib 使用 glob 时无效:

import glob

# These three lines return both files and directories
list(p.glob('*'))
list(p.glob('*/'))
glob.glob('*')

# Whereas this returns only directories
glob.glob('*/')

因此Path('./').glob('**')与 匹配相同的路径glob.glob('**/', recursive=True)

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

解决方案 6:

如果您需要一个能够找到子目录中所有子目录的递归解决方案,请按照之前的建议使用 walk。

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

解决方案 7:

仅列出目录

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

仅列出当前目录中的文件

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

解决方案 8:

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

d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))

解决方案 9:

使用 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)

解决方案 10:

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

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

解决方案 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.localhome$'))
print(subdirs)

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

解决方案 12:

尽管这个问题很久以前就得到了回答。我想建议使用该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

ETC。

解决方案 13:

复制粘贴方便ipython

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

输出自print(folders)

['folderA', 'folderB']

解决方案 14:

谢谢大家的提示。我遇到了一个问题,软链接(无限递归)被返回为目录。软链接?我们不想有臭臭的软链接!所以...

这仅渲染目录,而不是软链接:

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

解决方案 15:

以下是基于@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]

解决方案 16:

这是我的做法。

    import os
    for x in os.listdir(os.getcwd()):
        if os.path.isdir(x):
            print(x)

解决方案 17:

基于 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"

其中<your_directory>是您要遍历的目录的路径。

解决方案 18:

具有完整路径并考虑路径为.、、、等:..`\`..\..\subfolder

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

解决方案 19:

最简单的方法:

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] 

解决方案 20:

这个答案似乎还不存在。

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

解决方案 21:

我最近也遇到过类似的问题,我发现对于 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

递归版本如下所示:

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请参阅os.DirEntryentry

解决方案 22:

使用 os walk

sub_folders = []
for dir, sub_dirs, files in os.walk(test_folder):
    sub_folders.extend(sub_dirs)

解决方案 23:

这将列出文件树中的所有子目录。

import pathlib


def list_dir(dir):
    path = pathlib.Path(dir)
    dir = []
    try:
        for item in path.iterdir():
            if item.is_dir():
                dir.append(item)
                dir = dir + list_dir(item)
        return dir
    except FileNotFoundError:
        print('Invalid directory')

pathlib是 3.4 版中的新增内容

解决方案 24:

函数返回给定文件路径内所有子目录的列表。将搜索整个文件树。

import os

def get_sub_directory_paths(start_directory, sub_directories):
    """
    This method iterates through all subdirectory paths of a given 
    directory to collect all directory paths.

    :param start_directory: The starting directory path.
    :param sub_directories: A List that all subdirectory paths will be 
        stored to.
    :return: A List of all sub-directory paths.
    """

    for item in os.listdir(start_directory):
        full_path = os.path.join(start_directory, item)

        if os.path.isdir(full_path):
            sub_directories.append(full_path)

            # Recursive call to search through all subdirectories.
            get_sub_directory_paths(full_path, sub_directories)

return sub_directories

解决方案 25:

对于像我一样只需要目录内直接文件夹名称的人来说,这在 Windows 上是有效的。

import os

for f in os.scandir(mypath):
    print(f.name)

解决方案 26:

我们可以使用os.walk()获取所有文件夹的列表

import os

path = os.getcwd()

pathObject = os.walk(path)

这个pathObject是一个对象,我们可以通过以下方式获取一个数组

arr = [x for x in pathObject]

arr is of type [('current directory', [array of folder in current directory], [files in current directory]),('subdirectory', [array of folder in subdirectory], [files in subdirectory]) ....]

我们可以通过迭代arr并打印中间数组来获取所有子目录的列表

for i in arr:
   for j in i[1]:
      print(j)

这将打印所有子目录。

获取所有文件:

for i in arr:
   for j in i[2]:
      print(i[0] + "/" + j)

解决方案 27:

通过从这里加入多个解决方案,这就是我最终使用的解决方案:

import os
import glob

def list_dirs(path):
    return [os.path.basename(x) for x in filter(
        os.path.isdir, glob.glob(os.path.join(path, '*')))]

解决方案 28:

有很多不错的答案,但如果你来这里是为了寻找一种简单的方法来一次性获取所有文件或文件夹的列表。你可以利用 linux 和 mac 上提供的 os find,它比 os.walk 快得多

import os
all_files_list = os.popen("find path/to/my_base_folder -type f").read().splitlines()
all_sub_directories_list = os.popen("find path/to/my_base_folder -type d").read().splitlines()

或者

import os

def get_files(path):
    all_files_list = os.popen(f"find {path} -type f").read().splitlines()
    return all_files_list

def get_sub_folders(path):
    all_sub_directories_list = os.popen(f"find {path} -type d").read().splitlines()
    return all_sub_directories_list

解决方案 29:

这是一个简单的递归解决方案

import os
def fn(dir=r"C:UsersaryanDownloadsopendatakit"):  # 1.Get file names from directory
    file_list = os.listdir(dir)
    res = []
    # print(file_list)
    for file in file_list:
        if os.path.isfile(os.path.join(dir, file)):
                res.append(file)
        else:
            result = fn(os.path.join(dir, file))
            if result:
                res.extend(fn(os.path.join(dir, file)))
    return res


res = fn()
print(res)
print(len(res))

解决方案 30:

此函数使用给定的父级directory递归遍历其所有directories内容以及它在内部找到的prints所有内容filenames。非常有用。

import os

def printDirectoryFiles(directory):
   for filename in os.listdir(directory):  
        full_path=os.path.join(directory, filename)
        if not os.path.isdir(full_path): 
            print( full_path + "
")


def checkFolders(directory):

    dir_list = next(os.walk(directory))[1]

    #print(dir_list)

    for dir in dir_list:           
        print(dir)
        checkFolders(directory +"/"+ dir) 

    printDirectoryFiles(directory)       

main_dir="C:/Users/S0082448/Desktop/carpeta1"

checkFolders(main_dir)


input("Press enter to exit ;")

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用