How to list only top level directories in Python?
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.
Asked by: Tara506 | Posted: 28-01-2022
Answer 1
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.
Answer 2
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']
Answered by: Kelvin244 | Posted: 01-03-2022
Answer 3
Filter the list using os.path.isdir to detect directories.
filter(os.path.isdir, os.listdir(os.getcwd()))
Answered by: Lucas874 | Posted: 01-03-2022
Answer 4
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
Answered by: Kellan391 | Posted: 01-03-2022
Answer 5
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)
]
Answered by: Abigail361 | Posted: 01-03-2022
Answer 6
This seems to work too (at least on linux):
import glob, os
glob.glob('*' + os.path.sep)
Answered by: Elise737 | Posted: 01-03-2022
Answer 7
Using list comprehension,
[a for a in os.listdir() if os.path.isdir(a)]
I think It is the simplest way
Answered by: Alissa482 | Posted: 01-03-2022Answer 8
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.
Answered by: Chester811 | Posted: 01-03-2022Answer 9
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).
Answered by: Kelvin374 | Posted: 01-03-2022Answer 10
[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]
Answered by: Jack346 | Posted: 01-03-2022
Answer 11
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()]
Answered by: Patrick537 | Posted: 01-03-2022
Answer 12
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
.
Answered by: Alfred125 | Posted: 01-03-2022Using 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.
Answer 13
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.
Answered by: Lana725 | Posted: 01-03-2022Answer 14
2021 answer using glob
:
import glob, os
p = "/some/path/"
for d in glob.glob(p + "*" + os.path.sep):
print(d)
Answered by: Rafael723 | Posted: 01-03-2022
Answer 15
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))]
Answered by: Richard415 | Posted: 01-03-2022
Answer 16
scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]
Answered by: Miller543 | Posted: 01-03-2022
Answer 17
Like so?
>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]
Answered by: Patrick385 | Posted: 01-03-2022
Answer 18
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)
Answered by: Alina412 | Posted: 01-03-2022
Answer 19
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')]
Answered by: Jack881 | Posted: 01-03-2022
Answer 20
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 []
Answered by: Lyndon482 | Posted: 01-03-2022
Answer 21
-- 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
Answered by: Edward264 | Posted: 01-03-2022
Similar questions
filesystems - Python - Swap two file directories with each other
I have a robot and it is set up in a way to take commands from the front end of the website to then run a command on the robot. For example
if command == 'CF':
os.system('aplay /home/pi/sound/wavycf.wav')
I need somthing that will swap two files /images/hud.png and images/special/hud.png to each others directories....I hope that makes sense
filesystems - Python - Swap two file directories with each other
I have a robot and it is set up in a way to take commands from the front end of the website to then run a command on the robot. For example
if command == 'CF':
os.system('aplay /home/pi/sound/wavycf.wav')
I need somthing that will swap two files /images/hud.png and images/special/hud.png to each others directories....I hope that makes sense
filesystems - Python trouble importing modules
I am building a web app with this directory structure:
app/
__init__.py
config/
__init__.py
db_config.py
models/
__init__.py
model.py
datasources/
__init__.py
database.py
...
...
Every __init__.py file has
__all__ = ['', '', ...]
in it, listing the .py files that are in th...
filesystems - Python: Help with counters and writing files
This question already has answers here:
filesystems - Python: How do I create sequential file names?
I want my program to be able to write files in a sequential format, ie: file1.txt, file2.txt, file3.txt. It is only meant to write a single file upon execution of the code. It can't overwrite any existing files, and it MUST be created. I'm stumped.
filesystems - Python: problem with tiny script to delete files
I have a project that used to be under SVN, but now I'm moving it to Mercurial, so I want to clear out all the .svn files.
It's a little too big to do it by hand, so I decided to write a python script to do it. But it isn't working.
def cleandir(dir_path):
print "Cleaning %s\n" % dir_path
toDelete = []
files = os.listdir(dir_path)
for filedir in files:
print "considering %s" ...
windows - How can I enumerate filesystems from Python?
I'm using os.statvfs to find out the free space available on a volume -- in addition to querying free space for a particular path, I'd like to be able to iterate over all volumes. I'm working on Linux at the moment, but ideally would like something which returns ["/", "/boot", "home"] on Linux and ["C:\", "D:\"] on Windows.
filesystems - finding out absolute path to a file from python
If I have a file test.py that resides in some directory, how can I find out from test.py what directory it is in? os.path.curdir will give the current directory but not the directory where the file lives. If I invoke test.py from some directory foo, os.curdir will return foo but not the path of test.py.
thanks.
filesystems - Pythonic way to modify python path relative to current directory
I have a project that is structured like this (cut down a lot to give the gist)...
State_Editor/
bin/
state_editor/
__init__.py
main.py
features/
__init__.py
# .py files
io/
__init__.py
# .py files
# etc.
You get the idea. Now say for example that foobar.py in features ...
filesystems - Override file operations in Python
Is there a way to override all file operations in Python? File operations such as 'open', 'os.rename' and 'os.unlink'.
I want to create a temporary, in-memory file system without rewriting a library. Does anyone know of a script or a library that has this feature? I want to run a library on Google App Engine and it is not possible to write to the file system.
filesystems - Python - Remove accents from all files in folder
I'm trying to remove all accents from a all coding files in a folder.. I already have success in building the list of files, the problem is that when I try to use unicodedata to normalize I get the error:
** Traceback (most recent call last):
File "/usr/lib/gedit-2/plugins/pythonconsole/console.py", line 336, in __run
exec command in self.namespace
File "", line 2, in
UnicodeDecodeError: 'utf8' codec can't decode ...
filesystems - In Python, how can I get the file system of a given file path
In python, given a directory or file path like /usr/local, I need to get the file system where its available. In some systems it could be / (root) itself and in some others it could be /usr.
I tried os.statvfs it doesnt help. Do I have to run the df command with the path name and extract the file system from the output? Is there a better solution?
Its for linux/unix platforms only.
Thanks
Still can't find your answer? Check out these communities...
PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python