Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find recursively empty directories in Python?

Similarly to GNU find's find . -type d -empty -delete I'd like to find empty directories including those with empty subdirectories (and subdirectories containing emtpy subdirs etc.), but without deleting them. Is there any existing solution or do I have to manually use os.walk (probably with topdown=False and keeping track of the empty subdirectories found so far)?

like image 690
Tobias Kienzler Avatar asked Dec 25 '22 02:12

Tobias Kienzler


1 Answers

Here is a simple solution using a generator and os.walk:

import os

def find_empty_dirs(root_dir='.'):
    for dirpath, dirs, files in os.walk(root_dir):
        if not dirs and not files:
            yield dirpath

print list(find_empty_dirs())

I don't see why topdown=False is necessary, I don't think it changes anything.

This does consider directories that only contain empty directories to be non-empty themselves, but then so does find . -type d -empty.

Although, with some more testing, I see find . -type d -empty -delete does delete the empty subdirectories first, and then the higher directories if that made them empty. But using os.walk for that won't work, as it reads the list of subdirectories before descending, even with topdown=False.

A recursive solution that deletes empty subdirectory trees could be:

import os

def recursive_delete_if_empty(path):
    """Recursively delete empty directories; return True
    if everything was deleted."""

    if not os.path.isdir(path):
        # If you also want to delete some files like desktop.ini, check
        # for that here, and return True if you delete them.
        return False

    # Note that the list comprehension here is necessary, a
    # generator expression would shortcut and we don't want that!
    if all([recursive_delete_if_empty(os.path.join(path, filename))
            for filename in os.listdir(path)]):
        # Either there was nothing here or it was all deleted
        os.rmdir(path)
        return True
    else:
        return False
like image 104
RemcoGerlich Avatar answered Jan 03 '23 05:01

RemcoGerlich