How to Check if a Directory is Empty in Python
Detecting whether a folder contains files is a common automation task. While simple, performance matters significantly when the directory resides on a network drive or contains millions of files.
The Fastest Way: os.scandir()
Use os.scandir() (Python 3.5+). It returns an iterator rather than a list.
- Performance: Stops scanning as soon as it finds one entry
- Memory: O(1) space complexity (doesn't load all filenames)
import os
def is_dir_empty(path):
# 'with' ensures the iterator is closed properly
with os.scandir(path) as it:
# any() returns True if at least one item exists
return not any(it)
print(is_dir_empty("my_folder"))
Using pathlib for Readability
pathlib offers a more readable interface while wrapping the underlying OS calls.
from pathlib import Path
def is_empty_pathlib(path):
p = Path(path)
try:
# .iterdir() returns a generator
return not any(p.iterdir())
except FileNotFoundError:
return True # Or raise depending on requirements
print(is_empty_pathlib("my_folder"))
The Slow Way: os.listdir()
Avoid this method for large directories. os.listdir() builds a complete list of every filename in memory before you can check its length.
# ⛔️ Bad practice for large folders
import os
if len(os.listdir("huge_folder")) == 0:
print("Empty")
Handling Hidden Files
Standard methods count hidden files (like .DS_Store or .gitignore) as content. To treat a folder as empty when it contains only hidden files, filter by filename.
import os
def is_effectively_empty(path):
with os.scandir(path) as it:
for entry in it:
if not entry.name.startswith('.'):
return False # Found a visible file
return True
print(is_effectively_empty("my_folder"))
Checking with Error Handling
Production code should handle common edge cases gracefully.
from pathlib import Path
def check_directory_empty(path):
directory = Path(path)
if not directory.exists():
raise FileNotFoundError(f"Directory not found: {path}")
if not directory.is_dir():
raise NotADirectoryError(f"Path is not a directory: {path}")
try:
return not any(directory.iterdir())
except PermissionError:
raise PermissionError(f"Cannot access directory: {path}")
# Usage with error handling
try:
if check_directory_empty("/var/log/myapp"):
print("No log files found")
else:
print("Log files present")
except (FileNotFoundError, NotADirectoryError, PermissionError) as e:
print(f"Error: {e}")
Counting Files Without Loading All Names
When you need the count but want to avoid memory issues, use a generator expression.
from pathlib import Path
def count_items(path, max_count=None):
"""Count items, optionally stopping at max_count."""
directory = Path(path)
count = 0
for _ in directory.iterdir():
count += 1
if max_count and count >= max_count:
break
return count
# Check if directory has more than 100 items
item_count = count_items("downloads", max_count=101)
if item_count > 100:
print("Directory has more than 100 items")
else:
print("Directory has NOT more than 100 items")
Performance Comparison
| Method | Speed | Memory | Recommendation |
|---|---|---|---|
os.scandir() | Fast | Low | Best for performance-critical code |
pathlib.iterdir() | Fast | Low | Best for readability |
os.listdir() | Slow | High | Avoid for large directories |
Summary
Use pathlib.Path(p).iterdir() for general scripts where readability matters. Reserve os.scandir() for performance-critical applications or when working with extremely large directories. Always avoid os.listdir() when you only need to check emptiness, as it unnecessarily loads all filenames into memory.