Remove empty folders (Python)

Question:

This is the folder tree:

FOLDER\
       \1\file
       \2\file
       \3\
       \4\file

The script should scan (loop) for each folder in FOLDER and check if the sub-folders are empty or not. If they are, they must be deleted.

My code, until now, is this:

folders = ([x[0] for x in os.walk(os.path.expanduser('~\Desktop\FOLDER\DIGITS\'))])
folders2= (folders[1:])

This scan for folders and, using folders2 begin from the firs folder in DIGITS.
In DIGITS there are numbered directories: 1,2,3,4,etc

Now what? Tried using os.rmdir but it gives me an error, something about string. In fact, folders2 is a list, not a string, just saying…

Asked By: BlueTrack

||

Answers:

Not sure what kind of error you get, this works perfectly for me:

import os

root = 'FOLDER'
folders = list(os.walk(root))[1:]

for folder in folders:
    # folder example: ('FOLDER/3', [], ['file'])
    if not folder[2]:
        os.rmdir(folder[0])
Answered By: taras

Delete folder only if it is empty:

import os
import shutil

if len(os.listdir(folder_path)) == 0: # Check if the folder is empty
    shutil.rmtree(folder_path) # If so, delete it
Answered By: Gavriel Cohen

For empty folders deletion you can use this snippet.

import os


def drop_empty_folders(directory):
    """Verify that every empty folder removed in local storage."""

    for dirpath, dirnames, filenames in os.walk(directory, topdown=False):
        if not dirnames and not filenames:
            os.rmdir(dirpath)
Answered By: Insspb
import os

directory = r'path-to-directory'

for entry in os.scandir(directory):
    if os.path.isdir(entry.path) and not os.listdir(entry.path) :
        os.rmdir(entry.path)

Here you can find a good introduction/explanation to scandir

Answered By: Jácint Fodor

You can remove all empty folders and subfolder with the following snippet.

import os


def remove_empty_folders(path_abs):
    walk = list(os.walk(path_abs))
    for path, _, _ in walk[::-1]:
        if len(os.listdir(path)) == 0:
            os.remove(path)

if __name__ == '__main__':
    remove_empty_folders("your-path")
Answered By: Iván B.

Almost what Iván B. said but with a minor change that worked for me

import os, shutil
path_abs=('YourPath')
walk = list(os.walk(path_abs))
for path, _, _ in walk[::-1]:
    if len(os.listdir(path)) == 0:
        os.rmdir(path)
Answered By: xoelinho
#LOOP THROUGH ALL SUBFOLDERS FIRST

import os
root = os.getcwd() #CHANGE THIS TO PATH IF REQUIRED
folders = sorted(list(os.walk(root))[1:],reverse=True)
for folder in folders:
    try:
        os.rmdir(folder[0])
    except OSError as error: 
        print("Directory '{}' can not be removed".format(folder[0])) 

This should go through all the sub-folders first and remove if empty folders. Not deleting non empty folders that a parent folders.

I know it an old post but I am old myself !!!

Answered By: user1184628

A few things to expand on other answers:

If you use os.walk(topdown=False), it goes in reverse order, so you encounter the child directories before the parents. Then if you track which directories you’ve deleted, you can delete parent directories recursively.

import os


def delete_empty_folders(root):

    deleted = set()
    
    for current_dir, subdirs, files in os.walk(root, topdown=False):

        still_has_subdirs = any(
            _ for subdir in subdirs
            if os.path.join(current_dir, subdir) not in deleted
        )
    
        if not any(files) and not still_has_subdirs:
            os.rmdir(current_dir)
            deleted.add(current_dir)

    return deleted

Answered By: rcgale

This answer fixes issues in the current accepted answer. The major issue there is that the condition to remove a directory has to be not filenames and not dirnames.

import os

def remove_empty_directories(root):
    for dirpath, dirnames, filenames in os.walk(root):
        if not filenames and not dirnames:
            os.rmdir(dirpath)
Answered By: sidcha

I suggest that you call this function, It is designed with an optional argument.
If you set in_place to False it will not remove the folders it will just return them as a list. Meanwhile, if you set it to True the function will remove the empty folders regardless of the subdirectories tree depth.

P.S. In case you need a depth limitation you can analyze it by elements after root path.

import os
import shutil

def purge_dir(dir, in_place=False):

    deleted = []
    dir_tree = list(os.walk(dir, topdown=False))

    for tree_element in dir_tree:
        sub_dir = tree_element[0]
        is_empty = not len(os.listdir(sub_dir))
        if is_empty:
            deleted.append(sub_dir)

    if in_place:
        list(map(os.rmdir, deleted))

    return deleted

I suggest that you keep in_place set to False return back the empty folders and use it as you like since it is safer especially for security critical applications.

Answered By: haddagart

If you are on UNIX system, you can use the "find" command in a python script with subprocess.
You search for directories with : -type d
You select empty directories with : -empty
You delete these directories with : -delete
You launch the command with subprocess.run

import subprocess

command = "find {} -type d -empty -delete".format(folder_path)  
subprocess.run(command, shell=True)

It is just 3 lines code.

Following @tripleee’s advice, the code can be written like this :

import subprocess
path = "your path here"
command = ["find", path, "-type", "d", "-empty", "-delete"]
subprocess.run(command)
Answered By: McBeth

This one fixes the problem with all the other answers. It avoids giving you a PermissionDenied error which stops the program from deleting folders.

import os
import shutil

def remove_empty_folders(path_abs):
    walk = list(os.walk(path_abs))
    for path, _, _ in walk[::-1]:
        if len(os.listdir(path)) == 0:
            shutil.rmtree(path)
Answered By: Farnood Faraji
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.