791

Pythonで現在のディレクトリ内のすべてのサブディレクトリのリストを返す方法はありますか?

ファイルでこれを実行できることは知っていますが、代わりにディレクトリのリストを取得する必要があります。

4

32 に答える 32

801

直接のサブディレクトリを意味しますか、それともツリーのすぐ下にあるすべてのディレクトリを意味しますか?

os.walkいずれにせよ、これを行うために使用できます。

os.walk(directory)

サブディレクトリごとにタプルが生成されます。3タプルの最初のエントリはディレクトリ名であるため、

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

すべてのサブディレクトリを再帰的に提供する必要があります。

タプルの2番目のエントリは、最初の位置にあるエントリの子ディレクトリのリストであるため、代わりにこれを使用できますが、それほど節約できない可能性があります。

ただし、これを使用して、直接の子ディレクトリを提供することもできます。

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

または、「 Pythonですべての直接のサブディレクトリを取得する方法」のソリューションを含む、os.listdirおよびを使用してすでに投稿されている他のソリューションを参照してください。os.path.isdir

于 2009-06-10T02:54:45.913 に答える
252

あなたはただ使うことができますglob.glob

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

/. の後の末尾を忘れないでください*

于 2016-04-05T12:55:54.620 に答える
206
import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d) 
                    if os.path.isdir(os.path.join(d,o))]
于 2009-06-10T02:57:07.703 に答える
201

いくつかの 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.walkfast_scandir
os.walkos.scandir

  • 以下のコードを実行する場合は、必ず一度実行して、OS がフォルダーにアクセスし、結果を破棄してテストを実行してください。そうしないと、結果が台無しになります。
  • 関数呼び出しを混同したくなるかもしれませんが、私はそれをテストしましたが、それほど問題ではありませんでした。
  • すべての例で、フォルダへのフル パスが示されます。(Windows)Path オブジェクトとしての pathlib の例。
  • の最初の要素は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\t\t\ttook {(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\t\ttook {(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\ttook {(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\t\ttook {(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\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.\tFound dirs: {len(fu)}")


if __name__ == '__main__':
    run_os_scandir()
    run_os_walk()
    run_glob()
    run_pathlib_iterdir()
    run_os_listdir()
于 2016-10-31T17:23:29.010 に答える
46

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 でも利用できます。

于 2017-05-28T14:32:03.170 に答える
40

サブディレクトリ内のすべてのサブディレクトリを検索する再帰的なソリューションが必要な場合は、前に提案したようにウォークを使用してください。

現在のディレクトリの子ディレクトリのみが必要な場合はos.listdiros.path.isdir

于 2009-06-10T02:56:09.593 に答える
26

私はフィルター ( https://docs.python.org/2/library/functions.html#filter ) を使用することを好みますが、これは好みの問題です。

d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
于 2015-09-10T14:46:58.710 に答える
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)
于 2013-09-26T00:08:29.627 に答える
21

ディレクトリのみを一覧表示する

print("\nWe 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("\nThe following are the list of all files in the current directory -")
print(files)
于 2016-08-30T08:40:44.450 に答える
19

os.listdir(path) を使用して、Python 2.7 でサブディレクトリ (およびファイル) のリストを取得できます。

import os
os.listdir(path)  # list of subdirectories and files
于 2014-10-07T13:23:40.800 に答える
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

于 2016-07-07T12:06:46.447 に答える
10

ヒントをありがとう、みんな。ソフトリンク (無限再帰) がディレクトリとして返されるという問題に遭遇しました。ソフトリンク?悪臭を放つソフト リンクは必要ありません。そう...

これは、ソフトリンクではなくディレクトリのみをレンダリングしました。

>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
于 2013-05-10T18:38:40.233 に答える
8

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"

where<your_directory>は、トラバースするディレクトリへのパスです。

于 2016-01-04T21:19:33.880 に答える
1

このようなものに対してフィルター関数os.path.isdirを使用しますos.listdir()filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])

于 2016-02-08T01:30:14.547 に答える
1

この以下のクラスは、特定のディレクトリ内のファイル、フォルダー、およびすべてのサブフォルダーのリストを取得できます

import os
import json

class GetDirectoryList():
    def __init__(self, path):
        self.main_path = path
        self.absolute_path = []
        self.relative_path = []


    def get_files_and_folders(self, resp, path):
        all = os.listdir(path)
        resp["files"] = []
        for file_folder in all:
            if file_folder != "." and file_folder != "..":
                if os.path.isdir(path + "/" + file_folder):
                    resp[file_folder] = {}
                    self.get_files_and_folders(resp=resp[file_folder], path= path + "/" + file_folder)
                else:
                    resp["files"].append(file_folder)
                    self.absolute_path.append(path.replace(self.main_path + "/", "") + "/" + file_folder)
                    self.relative_path.append(path + "/" + file_folder)
        return resp, self.relative_path, self.absolute_path

    @property
    def get_all_files_folder(self):
        self.resp = {self.main_path: {}}
        all = self.get_files_and_folders(self.resp[self.main_path], self.main_path)
        return all

if __name__ == '__main__':
    mylib = GetDirectoryList(path="sample_folder")
    file_list = mylib.get_all_files_folder
    print (json.dumps(file_list))

サンプルディレクトリは次のように見えますが

sample_folder/
    lib_a/
        lib_c/
            lib_e/
                __init__.py
                a.txt
            __init__.py
            b.txt
            c.txt
        lib_d/
            __init__.py
        __init__.py
        d.txt
    lib_b/
        __init__.py
        e.txt
    __init__.py

得られた結果

[
  {
    "files": [
      "__init__.py"
    ],
    "lib_b": {
      "files": [
        "__init__.py",
        "e.txt"
      ]
    },
    "lib_a": {
      "files": [
        "__init__.py",
        "d.txt"
      ],
      "lib_c": {
        "files": [
          "__init__.py",
          "c.txt",
          "b.txt"
        ],
        "lib_e": {
          "files": [
            "__init__.py",
            "a.txt"
          ]
        }
      },
      "lib_d": {
        "files": [
          "__init__.py"
        ]
      }
    }
  },
  [
    "sample_folder/lib_b/__init__.py",
    "sample_folder/lib_b/e.txt",
    "sample_folder/__init__.py",
    "sample_folder/lib_a/lib_c/lib_e/__init__.py",
    "sample_folder/lib_a/lib_c/lib_e/a.txt",
    "sample_folder/lib_a/lib_c/__init__.py",
    "sample_folder/lib_a/lib_c/c.txt",
    "sample_folder/lib_a/lib_c/b.txt",
    "sample_folder/lib_a/lib_d/__init__.py",
    "sample_folder/lib_a/__init__.py",
    "sample_folder/lib_a/d.txt"
  ],
  [
    "lib_b/__init__.py",
    "lib_b/e.txt",
    "sample_folder/__init__.py",
    "lib_a/lib_c/lib_e/__init__.py",
    "lib_a/lib_c/lib_e/a.txt",
    "lib_a/lib_c/__init__.py",
    "lib_a/lib_c/c.txt",
    "lib_a/lib_c/b.txt",
    "lib_a/lib_d/__init__.py",
    "lib_a/__init__.py",
    "lib_a/d.txt"
  ]
]
于 2021-02-04T09:25:00.277 に答える
1

os ウォークの使用

sub_folders = []
for dir, sub_dirs, files in os.walk(test_folder):
    sub_folders.extend(sub_dirs)
于 2021-10-14T03:31:27.827 に答える