How to list only top level directories in Python?

PythonFilesystems

Python Problem Overview


I want to be able to list only the directories inside some folder. This means I don't want filenames listed, nor do I want additional sub-folders.

Let's see if an example helps. In the current directory we have:

>>> os.listdir(os.getcwd())
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'mod_p
ython-wininst.log', 'NEWS.txt', 'pymssql-wininst.log', 'python.exe', 'pythonw.ex
e', 'README.txt', 'Removemod_python.exe', 'Removepymssql.exe', 'Scripts', 'tcl',
 'Tools', 'w9xpopen.exe']

However, I don't want filenames listed. Nor do I want sub-folders such as \Lib\curses. Essentially what I want works with the following:

>>> for root, dirnames, filenames in os.walk('.'):
...     print dirnames
...     break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']

However, I'm wondering if there's a simpler way of achieving the same results. I get the impression that using os.walk only to return the top level is inefficient/too much.

Python Solutions


Solution 1 - Python

os.walk

Use os.walk with next item function:

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

For Python <=2.5 use:

os.walk('.').next()[1]
How this works

os.walk is a generator and calling next will get the first result in the form of a 3-tuple (dirpath, dirnames, filenames). Thus the [1] index returns only the dirnames from that tuple.

Solution 2 - Python

Filter the result using os.path.isdir() (and use os.path.join() to get the real path):

>>> [ name for name in os.listdir(thedir) if os.path.isdir(os.path.join(thedir, name)) ]
['ctypes', 'distutils', 'encodings', 'lib-tk', 'config', 'idlelib', 'xml', 'bsddb', 'hotshot', 'logging', 'doc', 'test', 'compiler', 'curses', 'site-packages', 'email', 'sqlite3', 'lib-dynload', 'wsgiref', 'plat-linux2', 'plat-mac']

Solution 3 - Python

Filter the list using os.path.isdir to detect directories.

filter(os.path.isdir, os.listdir(os.getcwd()))

Solution 4 - Python

directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]

Solution 5 - Python

Note that, instead of doing os.listdir(os.getcwd()), it's preferable to do os.listdir(os.path.curdir). One less function call, and it's as portable.

So, to complete the answer, to get a list of directories in a folder:

def listdirs(folder):
    return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

If you prefer full pathnames, then use this function:

def listdirs(folder):
    return [
        d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
        if os.path.isdir(d)
    ]

Solution 6 - Python

This seems to work too (at least on linux):

import glob, os
glob.glob('*' + os.path.sep)

Solution 7 - Python

Using list comprehension,

[a for a in os.listdir() if os.path.isdir(a)]

I think It is the simplest way

Solution 8 - Python

Just to add that using os.listdir() does not "take a lot of processing vs very simple os.walk().next()[1]". This is because os.walk() uses os.listdir() internally. In fact if you test them together:

>>>> import timeit
>>>> timeit.timeit("os.walk('.').next()[1]", "import os", number=10000)
1.1215229034423828
>>>> timeit.timeit("[ name for name in os.listdir('.') if os.path.isdir(os.path.join('.', name)) ]", "import os", number=10000)
1.0592019557952881

The filtering of os.listdir() is very slightly faster.

Solution 9 - Python

A very much simpler and elegant way is to use this:

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

Run this script in the same folder for which you want folder names.It will give you exactly the immediate folders name only(that too without the full path of the folders).

Solution 10 - Python

Python 3.4 introduced the pathlib module into the standard library, which provides an object oriented approach to handle filesystem paths:

from pathlib import Path

p = Path('./')
[f for f in p.iterdir() if f.is_dir()]

Solution 11 - Python

[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]

Solution 12 - Python

being a newbie here i can't yet directly comment but here is a small correction i'd like to add to the following part of ΤΖΩΤΖΙΟΥ's answer :

> If you prefer full pathnames, then use this function: > def listdirs(folder):
return [ d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder)) if os.path.isdir(d) ]

for those still on python < 2.4: the inner construct needs to be a list instead of a tuple and therefore should read like this:

def listdirs(folder):  
  return [
    d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
    if os.path.isdir(d)
  ]

otherwise one gets a syntax error.

Solution 13 - Python

You could also use os.scandir:

with os.scandir(os.getcwd()) as mydir:
    dirs = [i.name for i in mydir if i.is_dir()]

In case you want the full path you can use i.path.

> Using scandir() instead of listdir() can significantly increase the > performance of code that also needs file type or file attribute > information, because os.DirEntry objects expose this information if > the operating system provides it when scanning a directory.

Solution 14 - Python

2021 answer using glob:

import glob, os

p = "/some/path/"
for d in glob.glob(p + "*" + os.path.sep):
  print(d)

Solution 15 - Python

For a list of full path names I prefer this version to the other solutions here:

def listdirs(dir):
    return [os.path.join(os.path.join(dir, x)) for x in os.listdir(dir) 
        if os.path.isdir(os.path.join(dir, x))]

Solution 16 - Python

scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]

Solution 17 - Python

FWIW, the os.walk approach is almost 10x faster than the list comprehension and filter approaches:

In [30]: %timeit [d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
1.23 ms ± 97.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [31]: %timeit list(filter(os.path.isdir, os.listdir(os.getcwd())))
1.13 ms ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [32]: %timeit next(os.walk(os.getcwd()))[1]
132 µs ± 9.34 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Solution 18 - Python

Like so?

>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]

Solution 19 - Python

A safer option that does not fail when there is no directory.

def listdirs(folder):
    if os.path.exists(folder):
         return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
    else:
         return []

Solution 20 - Python

Using python 3.x with pathlib.Path.iter_dir

$ mkdir tmpdir
$ mkdir -p tmpdir/a/b/c
$ mkdir -p tmpdir/x/y/z

$ touch tmpdir/a/b/c/abc.txt
$ touch tmpdir/a/b/ab.txt
$ touch tmpdir/a/a.txt

$ python --version
Python 3.7.12
>>> from pathlib import Path
>>> tmpdir = Path("./tmpdir")
>>> [d for d in tmpdir.iterdir() if d.is_dir]
[PosixPath('tmpdir/x'), PosixPath('tmpdir/a')]
>>> sorted(d for d in tmpdir.iterdir() if d.is_dir)
[PosixPath('tmpdir/a'), PosixPath('tmpdir/x')]

Solution 21 - Python

-- This will exclude files and traverse through 1 level of sub folders in the root

def list_files(dir):
    List = []
    filterstr = ' '
    for root, dirs, files in os.walk(dir, topdown = True):
        #r.append(root)
        if (root == dir):
            pass
        elif filterstr in root:
            #filterstr = ' '
            pass
        else:
            filterstr = root
            #print(root)
            for name in files:
                print(root)
                print(dirs)
                List.append(os.path.join(root,name))
            #print(os.path.join(root,name),"\n")
                print(List,"\n")
            
    return List

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfuentesjrView Question on Stackoverflow
Solution 1 - PythonAlex CoventryView Answer on Stackoverflow
Solution 2 - PythonThomas WoutersView Answer on Stackoverflow
Solution 3 - PythonColin JensenView Answer on Stackoverflow
Solution 4 - PythonMark RoddyView Answer on Stackoverflow
Solution 5 - PythontzotView Answer on Stackoverflow
Solution 6 - PythonTravisView Answer on Stackoverflow
Solution 7 - PythonKBLeeView Answer on Stackoverflow
Solution 8 - PythonfozView Answer on Stackoverflow
Solution 9 - PythonmantyView Answer on Stackoverflow
Solution 10 - PythonjoelostblomView Answer on Stackoverflow
Solution 11 - PythonMoeView Answer on Stackoverflow
Solution 12 - PythonantiplexView Answer on Stackoverflow
Solution 13 - PythonG MView Answer on Stackoverflow
Solution 14 - PythonPedro LobitoView Answer on Stackoverflow
Solution 15 - PythonMalius ArthView Answer on Stackoverflow
Solution 16 - PythonnvdView Answer on Stackoverflow
Solution 17 - PythonpandichefView Answer on Stackoverflow
Solution 18 - PythonKirk StrauserView Answer on Stackoverflow
Solution 19 - PythonAlexey GavrilovView Answer on Stackoverflow
Solution 20 - PythonDarren WeberView Answer on Stackoverflow
Solution 21 - Pythonvenkata maddineniView Answer on Stackoverflow