9

Получение списка всех подпапок в текущем каталоге

13

Есть ли способ получить список всех подпапок в текущей директории на Python?

Я понимаю, что можно получить список файлов, но мне нужно получить список именно директорий.

5 ответ(ов)

3

Вот перевод вашего текста на русский язык в стиле ответа на StackOverflow:


Гораздо удобнее, чем вышеописанные методы, так как вам не нужно использовать несколько os.path.join(), и вы получите полный путь напрямую (если захотите). Это можно сделать в Python 3.5 и выше.

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

Этот код выдаст полный путь к подкаталогу. Если вам нужно только имя подкаталога, используйте f.name вместо f.path.

Дополнительная информация: документация по os.scandir.


Немного оффтоп: если вам нужны все подкаталоги рекурсивно и/или все файлы рекурсивно, посмотрите на эту функцию, она быстрее, чем os.walk и glob, и вернет список всех подкаталогов, а также всех файлов внутри этих (под-)каталогов: ссылка на StackOverflow.

Если вы хотите получить только все подкаталоги рекурсивно:

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.


Анализ всех функций

Суть:

  • Если вам нужны только непосредственные подкаталоги для папки, используйте os.scandir.
  • Если вам нужны все подкаталоги, включая вложенные, используйте os.walk или, немного быстрее, функцию fast_scandir выше.
  • Никогда не используйте os.walk для получения только подкаталогов верхнего уровня, так как это может быть в сотни(!) раз медленнее, чем os.scandir.
  • Если вы запустите приведенный ниже код, убедитесь, что вы выполнили его один раз, чтобы ваша ОС получила доступ к папке, сбросьте результаты и запустите тест, иначе результаты будут искаженными.
  • Вы можете перемешать вызовы функций, но я тестировал это, и это не имеет большого значения.
  • Все примеры будут возвращать полный путь к папке, пример с pathlib будет в виде объекта (Windows)Path.
  • Первый элемент результата os.walk это базовая папка. Так что вы не получите только подкаталоги. Вы можете использовать fu.pop(0), чтобы его удалить.
  • Ни один из результатов не использует естественную сортировку. Это означает, что результаты будут отсортированы следующим образом: 1, 10, 2. Чтобы получить естественную сортировку (1, 2, 10), посмотрите на это.

Результаты:

os.scandir      заняло   1 мс. Найдено каталогов: 439
os.walk         заняло 463 мс. Найдено каталогов: 441 -> нашел вложенный + базовый каталог.
glob.glob       заняло  20 мс. Найдено каталогов: 439
pathlib.iterdir заняло  18 мс. Найдено каталогов: 439
os.listdir      заняло  18 мс. Найдено каталогов: 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"<вставьте_папку>"
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. Найдено каталогов: {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. Найдено каталогов: {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. Найдено каталогов: {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. Найдено каталогов: {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.\tНайдено каталогов: {len(fu)}")

if __name__ == '__main__':
    run_os_scandir()
    run_os_walk()
    run_glob()
    run_pathlib_iterdir()
    run_os_listdir()

Надеюсь, это поможет!

3

Вы можете просто использовать glob.glob:

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

Не забудьте добавить слеш / после *.

2

Этот код на Python создает список полных путей к директориям, находящимся в текущем каталоге. Давайте разберем его по шагам:

  1. Импортируется модуль os, который предоставляет функции для взаимодействия с операционной системой.
  2. Переменная d устанавливается равной строке '.', что обозначает текущую директорию.
  3. Списковое включение (list comprehension) используется для создания списка.
  4. Внутри спискового включения вызывается os.listdir(d), который возвращает список имен всех файлов и каталогов в текущем каталоге.
  5. Затем для каждого элемента o в этом списке создается полный путь с помощью os.path.join(d, o).
  6. Условие if os.path.isdir(os.path.join(d,o)) проверяет, является ли данный путь директорией. Если да, то путь добавляется в результирующий список.

Итак, итогом выполнения данного кода будет список путей ко всем подкаталогам в текущей директории. Если у вас есть дополнительные вопросы или вам нужна помощь с чем-то еще, не стесняйтесь спрашивать!

0

Если вам нужно рекурсивное решение для поиска всех подкаталогов во вложенных директориях, используйте функцию os.walk, как было предложено ранее.

Если же вам нужны только дочерние каталоги текущей директории, вы можете объединить os.listdir с os.path.isdir, чтобы фильтровать только каталоги. Вот пример кода на Python:

import os

current_directory = "ваша_директория_здесь"
child_directories = [d for d in os.listdir(current_directory) if os.path.isdir(os.path.join(current_directory, d))]

print(child_directories)

Этот код создаст список всех дочерних каталогов в указанной директории.

0

Вывод только директорий

print("\nМы выводим только директории в текущей папке -")
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("\nНиже представлен список всех файлов в текущей папке -")
print(files)

Если у вас есть другие вопросы или нужна дополнительная помощь, не стесняйтесь спрашивать!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь