2009-06-10 5 views
290

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

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

+0

https://docs.python.org/3.4/library/os.html?highlight=os#os.listdir https://docs.python.org/3.4/library/os.path.html# os.path.isdir –

ответ

333

Вы имеете в виду немедленные подкаталоги или все каталоги прямо вниз по дереву?

В любом случае, вы могли бы использовать os.walk, чтобы сделать это:

os.walk(directory) 

даст кортеж для каждого подкаталога. Ths первая запись в 3-кортеж является имя каталога, так

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

должно дать вам все подкаталоги, рекурсивно.

Обратите внимание, что вторая запись в кортеже - это список дочерних каталогов записи в первой позиции, поэтому вы можете использовать это вместо этого, но это вряд ли поможет вам значительно сэкономить.

Однако, вы можете использовать его только, чтобы дать вам непосредственные дочерние каталоги:

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

Или увидеть другие решения уже размещены, используя os.listdir и os.path.isdir, в том числе на «How to get all of the immediate subdirectories in Python».

+6

Я думаю, что os.walk возвращает тройки (root, dirs, files). Это означает, что у dirs много повторных записей. Есть ли более эффективный способ, который повторяется через каталоги? – mathtick

+0

@mathtick, dirs не будут повторяться - только одна запись в подкаталоге –

+13

Не используйте '' os.walk ('.'). Next() [1] '' или '' os.walk ('.') .__ next __() [1] '' непосредственно. Вместо этого используйте встроенную функцию '' next() '', которая доступна как в [Python 2 (см. Doc)] (https://docs.python.org/2/library/functions.html#next) и [Python 3 (см. doc)] (https://docs.python.org/3/library/functions.html#next). Например: '' next (os.walk ('.')) [1] ''. –

29

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

Если вам нужны только дочерние каталоги из текущего каталога, в скомбинировать os.listdir с os.path.isdir

103
import os 

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

Обратите внимание, что при таком подходе вам нужно ухаживать за проблемами abspath, если они не выполняются на '.' – daspostloch

+3

Если вы не используете cwd ('.'), Это не сработает, если вы не выполните 'os.path.join' на' o', чтобы получить полный путь, иначе 'isdir (0) 'всегда будет возвращать false –

+2

Похоже, что сообщение было обновлено исправлениями для двух упомянутых выше проблем. – cgmb

5

Спасибо за советы, ребята. Я столкнулся с проблемой, когда softlinks (бесконечная рекурсия) возвращаются как dirs. Softlinks? Мы не хотим никаких бесплатных ссылок! Так что ...

Это сделало только те каталоги, а не softlinks:

>>> import os 
>>> inf = os.walk('.') 
>>> [x[0] for x in inf] 
['.', './iamadir'] 
+0

Что такое '[x [0] for x in inf]', вызываемый в python, чтобы я мог его посмотреть? – shinzou

+0

@shinzou Это понимание списка. Супер полезно. Также посмотрите на понимание диктата. – KurtB

14

Реализовано это с помощью питона-Os-прогулку. (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) 
4

С полным путем и учета пути, по которому ' '' .. ' '\',' .. \ .. \ подпапка', и т.д.

import os, pprint 
pprint.pprint([os.path.join(os.path.abspath(path), x[0]) for x in os.walk(os.path.abspath(path))]) 
9

You может получить список подкаталогов (и файлов) в Python 2.7, используя os.listdir (путь)

import os 
os.listdir(path) # list of subdirectories and files 
+43

Сюда также входят файлы. –

+1

Имя путается, так как 'dir' не относится к объектам, образующим список, а к каталогу контейнера. Пожалуйста, проверьте свои однострочные ответы, для новичков очень заманчиво выбрать их. – Titou

+1

Остерегайтесь того, что 'os.listdir' перечисляет содержимое каталога, включая файлы. – guneysus

5

Так как я наткнулся на эту проблему с помощью Python 3.4 и пути для Windows UNC, вот вариант для этой среды:

from pathlib import WindowsPath 

def SubDirPath (d): 
    return [f for f in d.iterdir() if f.is_dir()] 

subdirs = SubDirPath(WindowsPath(r'\\file01.acme.local\home$')) 
print(subdirs) 

Pathlib является новым в Python 3.4 и упрощает работу с путями в разных ОС: https://docs.python.org/3.4/library/pathlib.html

5

Опираясь на решения Эли Бендерский, используйте следующий пример:

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" 

где <your_directory> путь к директории, которую вы хотите пройти.

0

использовать функцию фильтра os.path.isdir над os.listdir() что-то вроде этого filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])

64

Вы могли бы просто использовать glob.glob

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

Не забудьте лидирующий / после *.

3

Хотя на этот вопрос ответили давно. Я хочу рекомендовать использовать модуль pathlib, так как это надежный способ работы с ОС Windows и Unix.

Таким образом, чтобы получить все пути в определенной директории, включая подкаталоги:

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 

т.д.

3

Листинг только каталоги

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) 
+2

Не работает на Mac OS. Я думаю, что проблема в том, что os.listdir возвращает только имя каталога, а не полный путь, но os.path.isdir возвращает True, если полный путь - это каталог. – denson

16

Намного приятнее, чем выше, потому что вам не нужно несколько 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

+0

Как видно из ссылки на библиотеку, это доступно только в python 3 (в частности, 3.5) – Dannid

+7

Возможно, поэтому я написал 'вы можете сделать это в Python 3.5 +' жирным шрифтом, когда я написал свой пост ... – user136036

3

Этот ответ, похоже, не существует уже.

directories = [ x for x in os.listdir('.') if os.path.isdir(x) ] 
+6

Это будет всегда возвращайте пустой список, если вы ищете что-либо иное, чем текущий рабочий каталог, что технически то, что OP ищет, но не очень многократно используемое. – ochawkeye

+0

каталогов = [x для x в os.listdir (localDir), если os.path.isdir (localDir + x) – Poonam

2

Python 3.4 введен the pathlib module в стандартную библиотеку, которая обеспечивает подход объектно-ориентированный обрабатывать пути файловой системы:

from pathlib import Path 

p = Path('./') 

# List comprehension 
[f for f in p.iterdir() if f.is_dir()] 

# The trailing slash to glob indicated directories 
# This will also include the current directory '.' 
list(p.glob('**/')) 

Pathlib также доступна на Python 2.7 с помощью the pathlib2 module on PyPi.

-1

Если вы хотите просто папку верхнего списка, пожалуйста, используйте listdir, так как прогулка займет слишком много времени.

5

Вот несколько простых функций на основе примера @Blair Конрада -

import os 

def get_subdirs(dir): 
    "Get a list of immediate subdirectories" 
    return next(os.walk(dir))[1] 

def get_subfiles(dir): 
    "Get a list of immediate subfiles" 
    return next(os.walk(dir))[2] 
0

Я имел подобный вопрос в последнее время, и я узнал, что лучший ответ на питон 3.5 и выше является использование os.scandir. Поскольку кажется, что нет решения, использующего его, я добавлю свое. Во-первых, нерекурсивное решение, в котором перечислены только подкаталоги прямо под корневым каталогом.

def get_dirlist(rootdir): 

    dirlist = [] 

    with os.scandir(rootdir) as rit: 
     for entry in rit: 
      if not entry.name.startswith('.') and entry.is_dir(): 
       dirlist.append(entry.path) 

    dirlist.sort() # Optional, in case you want sorted directory names 
    return dirlist 

Рекурсивная версия будет выглядеть следующим образом:

def get_dirlist(rootdir): 

    dirlist = [] 

    with os.scandir(rootdir) as rit: 
     for entry in rit: 
      if not entry.name.startswith('.') and entry.is_dir(): 
       dirlist.append(entry.path) 
       dirlist += get_dirlist(entry.path) 

    dirlist.sort() # Optional, in case you want sorted directory names 
    return dirlist 

иметь в виду, что entry.path владеет абсолютный путь к поддиректории. Если вам нужно только имя папки, вместо этого вы можете использовать entry.name. Обратитесь к os.DirEntry за дополнительной информацией о объекте entry.

Смежные вопросы