Pythonで現在のディレクトリ内のすべてのサブディレクトリのリストを返す方法はありますか?
ファイルでこれを実行できることは知っていますが、代わりにディレクトリのリストを取得する必要があります。
Pythonで現在のディレクトリ内のすべてのサブディレクトリのリストを返す方法はありますか?
ファイルでこれを実行できることは知っていますが、代わりにディレクトリのリストを取得する必要があります。
直接のサブディレクトリを意味しますか、それともツリーのすぐ下にあるすべてのディレクトリを意味しますか?
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
あなたはただ使うことができますglob.glob
from glob import glob
glob("/path/to/directory/*/", recursive = True)
/
. の後の末尾を忘れないでください*
。
import os
d = '.'
[os.path.join(d, o) for o in os.listdir(d)
if os.path.isdir(os.path.join(d,o))]
いくつかの 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
os.walk
ベース フォルダーになります。したがって、サブディレクトリだけを取得することはできません。使っfu.pop(0)
て外せます。結果:
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()
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 でも利用できます。
サブディレクトリ内のすべてのサブディレクトリを検索する再帰的なソリューションが必要な場合は、前に提案したようにウォークを使用してください。
現在のディレクトリの子ディレクトリのみが必要な場合はos.listdir
、os.path.isdir
私はフィルター ( https://docs.python.org/2/library/functions.html#filter ) を使用することを好みますが、これは好みの問題です。
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/ )
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)
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)
os.listdir(path) を使用して、Python 2.7 でサブディレクトリ (およびファイル) のリストを取得できます。
import os
os.listdir(path) # list of subdirectories and files
この質問はずっと前に回答されていますが。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
等
ヒントをありがとう、みんな。ソフトリンク (無限再帰) がディレクトリとして返されるという問題に遭遇しました。ソフトリンク?悪臭を放つソフト リンクは必要ありません。そう...
これは、ソフトリンクではなくディレクトリのみをレンダリングしました。
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
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>
は、トラバースするディレクトリへのパスです。
このようなものに対してフィルター関数os.path.isdir
を使用しますos.listdir()
filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])
この以下のクラスは、特定のディレクトリ内のファイル、フォルダー、およびすべてのサブフォルダーのリストを取得できます
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"
]
]
os ウォークの使用
sub_folders = []
for dir, sub_dirs, files in os.walk(test_folder):
sub_folders.extend(sub_dirs)