現在のディレクトリ内のすべてのサブディレクトリのリストを取得する

2009年06月10日に質問されました。  ·  閲覧回数 835.7k回  ·  ソース

Brad Zeis picture
2009年06月10日

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

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

回答

Blair Conrad picture
2009年06月10日
659

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

どちらの方法でも、 os.walkを使用してこれを行うことができます。

os.walk(directory)

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

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

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

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

ただし、直接の子ディレクトリを提供するためだけに使用できます。

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

または、 os.listdiros.path.isdirを使用して、すでに投稿されている他のソリューションを参照してください。これには、

Udit Bansal picture
2016年04月05日
184

glob.glob使用できます

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

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

gahooa picture
2009年06月10日
180
import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d) 
                    if os.path.isdir(os.path.join(d,o))]
user136036 picture
2016年11月01日
133

上記よりもはるかに良く、あなたはいくつかの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.walkglobよりも高速で、すべてのサブフォルダーのリストを次のように返します。これらの(サブ)サブフォルダー内のすべてのファイルと同様に: https

すべてのサブフォルダーのみを

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.scandirよりも数百倍遅くなる可能性があるため、トップレベルのサブディレクトリにのみos.walkを使用しないでください。

  • 以下のコードを実行する場合は、OSがフォルダーにアクセスするように一度実行し、結果を破棄してテストを実行してください。そうしないと、結果が失敗します。
  • 関数呼び出しを混同したいと思うかもしれませんが、私はそれをテストしました、そしてそれは実際には問題ではありませんでした。
  • すべての例で、フォルダーへのフルパスが示されます。 (Windows)Pathオブジェクトとしてのpathlibの例。
  • os.walkの最初の要素は、ベースフォルダーになります。 したがって、サブディレクトリだけを取得することはできません。 fu.pop(0)を使用して削除できます。
  • どの結果も自然順を使用しません。 つまり、結果は次のように並べ替えられます:1、10、2。自然並べ替え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、Python3.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()
Eli Bendersky picture
2009年06月10日
34

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

現在のディレクトリの子ディレクトリのみが必要な場合は、 os.listdiros.path.isdir組み合わせます

svelten picture
2015年09月10日
25

私はフィルター( https://docs.python.org/2/library/functions.html#filter )を使用することを好み

d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
Charith De Silva picture
2013年09月26日
21

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)
joelostblom picture
2017年05月28日
18

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モジュールを介し

Oscar Martin picture
2014年10月07日
17

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

import os
os.listdir(path)  # list of subdirectories and files
NutJobb picture
2016年08月30日
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)

現在のディレクトリ内のファイルのみを一覧表示する

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