[python] 파이썬에서 직접 하위 디렉토리를 모두 얻는 방법

모든 하위 디렉토리의 index.tpl을 index.html에 복사하는 간단한 Python 스크립트를 작성하려고합니다 (몇 가지 예외가 있음).

하위 디렉토리 목록을 가져 와서 혼란에 빠졌습니다.



답변

모든 현재 하위 디렉토리 의 전체 경로 를 반환하기 위해 다양한 기능에 대한 속도 테스트수행 했습니다 .

tl; dr :
항상 사용 scandir:

list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]

보너스 : scandir를 사용하는 f.name대신을 사용하여 폴더 이름 만 가져올 수도 있습니다 f.path.

이것 (및 아래의 다른 모든 기능)은 자연 정렬을 사용하지 않습니다 . 즉, 결과는 1, 10, 2로 정렬됩니다. 자연 정렬 (1, 2, 10)을 얻으려면 https://stackoverflow.com/a/48030307/2441026참조하십시오.


결과 :
scandiris : 3 배 이상 walk, 32 배 이상 listdir(필터 포함), 35 배 이상 Pathlib, 36 배 이상 listdir, 37 배 (!) 빠릅니다 glob.

Scandir:           0.977
Walk:              3.011
Listdir (filter): 31.288
Pathlib:          34.075
Listdir:          35.501
Glob:             36.277

W7x64, Python 3.8.1로 테스트되었습니다. 440 개의 하위 폴더가있는 폴더 os.path.join ()을 두 번 수행하지 않고 속도를 높일 수
있는지 궁금한 경우 listdir에는 기본적으로 차이가 없습니다.

암호:

import os
import pathlib
import timeit
import glob

path = r"<example_path>"



def a():
    list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]
    # print(len(list_subfolders_with_paths))


def b():
    list_subfolders_with_paths = [os.path.join(path, f) for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))]
    # print(len(list_subfolders_with_paths))


def c():
    list_subfolders_with_paths = []
    for root, dirs, files in os.walk(path):
        for dir in dirs:
            list_subfolders_with_paths.append( os.path.join(root, dir) )
        break
    # print(len(list_subfolders_with_paths))


def d():
    list_subfolders_with_paths = glob.glob(path + '/*/')
    # print(len(list_subfolders_with_paths))


def e():
    list_subfolders_with_paths = list(filter(os.path.isdir, [os.path.join(path, f) for f in os.listdir(path)]))
    # print(len(list(list_subfolders_with_paths)))


def f():
    p = pathlib.Path(path)
    list_subfolders_with_paths = [x for x in p.iterdir() if x.is_dir()]
    # print(len(list_subfolders_with_paths))



print(f"Scandir:          {timeit.timeit(a, number=1000):.3f}")
print(f"Listdir:          {timeit.timeit(b, number=1000):.3f}")
print(f"Walk:             {timeit.timeit(c, number=1000):.3f}")
print(f"Glob:             {timeit.timeit(d, number=1000):.3f}")
print(f"Listdir (filter): {timeit.timeit(e, number=1000):.3f}")
print(f"Pathlib:          {timeit.timeit(f, number=1000):.3f}")


답변

import os
def get_immediate_subdirectories(a_dir):
    return [name for name in os.listdir(a_dir)
            if os.path.isdir(os.path.join(a_dir, name))]


답변

왜 아무도 언급하지 않았 glob습니까? glob유닉스 스타일의 경로 이름 확장을 사용할 수 있으며, 둘 이상의 경로 이름을 찾는 데 필요한 거의 모든 기능을 수행합니다. 매우 쉽습니다.

from glob import glob
paths = glob('*/')

glob(유닉스처럼) 최종 슬래시 디렉토리를 반환합니다 대부분의 동안path 기반 솔루션이 최종 슬래시를 생략합니다.


답변

현재 디렉토리의 모든 서브 디렉토리 목록 가져 오기 .

다음은 Python 3 버전입니다.

import os

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

print(dir_list)


답변

import os, os.path

디렉토리에 (전체 경로) 즉시 하위 디렉토리를 가져 오려면 다음을 수행하십시오.

def SubDirPath (d):
    return filter(os.path.isdir, [os.path.join(d,f) for f in os.listdir(d)])

최신 (최신) 서브 디렉토리를 확보하려면 다음을 수행하십시오.

def LatestDirectory (d):
    return max(SubDirPath(d), key=os.path.getmtime)


답변

os.walk 이 상황에서 당신의 친구입니다.

설명서에서 직접 :

walk ()는 트리를 위에서 아래로 또는 아래로 걸어서 디렉토리 트리에 파일 이름을 생성합니다. 디렉토리 상단 (상단 자체 포함)을 기반으로하는 트리의 각 디렉토리에 대해 3 개의 튜플 (dirpath, dirnames, filenames)이 생성됩니다.


답변

이 방법은 한 번에 모두 잘 수행합니다.

from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]