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

파이썬에서 현재 디렉토리의 모든 하위 디렉토리 목록을 반환하는 방법이 있습니까?

파일 로이 작업을 수행 할 수 있다는 것을 알고 있지만 대신 디렉토리 목록을 가져와야합니다.



답변

즉각적인 서브 디렉토리 또는 트리 바로 아래의 모든 디렉토리를 의미합니까?

어느 쪽이든, 당신 os.walk은 이것을 할 수 있습니다 :

os.walk(directory)

각 하위 디렉토리에 대한 튜플을 생성합니다. 3- 튜플의 첫 번째 항목은 디렉토리 이름이므로

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

모든 하위 디렉토리를 재귀 적으로 제공해야합니다.

튜플의 두 번째 항목은 첫 번째 위치에있는 항목의 하위 디렉토리 목록이므로이를 대신 사용할 수는 있지만 크게 절약 할 수는 없습니다.

그러나 즉시 하위 디렉토리를 제공하기 위해 사용할 수 있습니다.

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

아니면 다른 솔루션 이미 게시하여 참조 os.listdiros.path.isdir“에 포함, 파이썬에서 즉시 모든 하위 디렉터리를 얻을 수 있습니다 “를.


답변

import os

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


답변

당신은 그냥 사용할 수 있습니다 glob.glob

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

의 후행 /을 잊지 마십시오 *.


답변

여러 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가 폴더에 액세스하고 결과를 버리고 테스트를 실행하도록 코드를 한 번 실행해야합니다. 그렇지 않으면 결과가 고정됩니다.
  • 함수 호출을 혼합하고 싶을 수도 있지만 테스트했지만 실제로는 중요하지 않았습니다.
  • 모든 예제는 폴더의 전체 경로를 제공합니다. (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()


답변

서브 디렉토리에서 모든 서브 디렉토리를 찾을 수있는 재귀 솔루션이 필요한 경우 이전에 제안한대로 walk를 사용하십시오.

당신은 현재 디렉토리의 하위 디렉토리가 필요한 경우, 결합 os.listdiros.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)