- os.listdir() — the simplest way to list files
- Filtering — finding specific files
- glob — pattern matching for files
- os.walk() — exploring subdirectories
- File information — getting details about files
- Error handling — dealing with missing directories
Seeing What's in a Folder
Have you ever looked inside a folder and wondered what's in there? In Python, you can do the same thing programmatically. Listing files in a directory is one of the most common tasks in programming — whether you're processing data, organizing files, or building applications.
Think of it like opening a drawer and looking at everything inside. Python gives you several ways to do this, from simple listings to finding specific files matching patterns.
💡 Key concept: Listing files is the foundation of file management. Once you can see what's in a directory, you can read, write, move, copy, or delete files as needed.
Using os.listdir()
The Simplest Way to List Files
# os.listdir() gives you everything in a directory
import os
# Create some sample files
with open("file1.txt", "w") as f:
f.write("Sample file 1")
with open("file2.txt", "w") as f:
f.write("Sample file 2")
with open("file3.txt", "w") as f:
f.write("Sample file 3")
# 1. List everything in the current directory
print("All items in current directory:")
items = os.listdir(".")
for item in items:
print(f" {item}")
# 2. List everything in a specific directory
items = os.listdir(".")
print(f"\nNumber of items: {len(items)}")
# 3. List files in a different directory
# os.listdir("/path/to/directory")
# 4. Check what's inside a directory without changing to it
home = os.path.expanduser("~")
print(f"\nItems in home directory: {len(os.listdir(home))} items")
# 5. List only files (not directories)
def list_only_files(directory):
"""List only files, not directories"""
all_items = os.listdir(directory)
files = []
for item in all_items:
full_path = os.path.join(directory, item)
if os.path.isfile(full_path):
files.append(item)
return files
print(f"\nFiles only: {list_only_files('.')}")
# 6. List only directories
def list_only_directories(directory):
"""List only directories, not files"""
all_items = os.listdir(directory)
dirs = []
for item in all_items:
full_path = os.path.join(directory, item)
if os.path.isdir(full_path):
dirs.append(item)
return dirs
print(f"Directories only: {list_only_directories('.')}")
# 7. Sorting the list
items = sorted(os.listdir("."))
print(f"\nSorted items: {items}")
os.listdir() key points:
- Returns a list — all items in the directory as strings
- Includes everything — files, directories, hidden files
- Not sorted — order is system-dependent
- Simple and fast — great for quick listings
- Use os.path.join() — to get full paths
Quick Check: What does os.listdir() return? (Answer: A list of strings with file and directory names)
Filtering Files
Finding What You're Looking For
# Often you don't want everything — you want specific files
import os
# Create some files with different extensions
with open("data.csv", "w") as f:
f.write("name,age\nAlice,25")
with open("data.json", "w") as f:
f.write('{"name": "Alice", "age": 25}')
with open("data.txt", "w") as f:
f.write("This is a text file")
with open("image.jpg", "w") as f:
f.write("Pretend this is a JPG image")
with open("document.pdf", "w") as f:
f.write("Pretend this is a PDF")
# 1. Filter by extension
def find_files_by_extension(directory, extension):
"""Find all files with a specific extension"""
files = []
for item in os.listdir(directory):
if item.endswith(extension):
files.append(item)
return files
print(f"CSV files: {find_files_by_extension('.', '.csv')}")
print(f"Text files: {find_files_by_extension('.', '.txt')}")
# 2. Filter by name pattern
def find_files_by_pattern(directory, pattern):
"""Find files containing a pattern in the name"""
files = []
for item in os.listdir(directory):
if pattern in item:
files.append(item)
return files
print(f"Files with 'data': {find_files_by_pattern('.', 'data')}")
# 3. Filter with multiple conditions
def find_specific_files(directory, extensions=None, min_size=None):
"""Find files with multiple conditions"""
files = []
for item in os.listdir(directory):
full_path = os.path.join(directory, item)
if not os.path.isfile(full_path):
continue
# Check extension
if extensions and not any(item.endswith(ext) for ext in extensions):
continue
# Check size
if min_size and os.path.getsize(full_path) < min_size:
continue
files.append(item)
return files
print(f"Files that are CSV or JSON: {find_specific_files('.', ['.csv', '.json'])}")
# 4. List comprehension approach (more concise)
files = [f for f in os.listdir(".") if f.endswith(".txt")]
print(f"Using list comprehension: {files}")
Filtering key points:
- Extension filtering — use endswith()
- Pattern matching — use "in" operator
- Multiple conditions — combine checks
- List comprehensions — concise and readable
Quick Check: How do you filter files by extension? (Answer: Use the endswith() method)
Using glob for Pattern Matching
Finding Files with Wildcards
# The glob module lets you use wildcards to find files
import glob
# Create some files for testing
for i in range(5):
with open(f"file_{i}.txt", "w") as f:
f.write(f"File {i}")
with open("data_2026.csv", "w") as f:
f.write("data for 2026")
with open("data_2027.csv", "w") as f:
f.write("data for 2027")
# 1. Simple pattern matching
txt_files = glob.glob("*.txt")
print(f"All text files: {txt_files}")
# 2. Matching specific patterns
csv_files = glob.glob("*.csv")
print(f"All CSV files: {csv_files}")
# 3. Matching with wildcards
files_with_number = glob.glob("file_?.txt") # ? matches exactly one character
print(f"Files with one digit: {files_with_number}")
# 4. Matching ranges
data_files = glob.glob("data_*.csv")
print(f"Data files: {data_files}")
# 5. Matching multiple patterns
import glob
# This is equivalent to:
# data = glob.glob("*.csv") + glob.glob("*.txt")
# print(f"All CSV and text files: {data}")
# 6. Recursive glob (Python 3.5+)
# glob.glob("**/*.txt", recursive=True)
# 7. Getting full paths
full_paths = [os.path.abspath(f) for f in glob.glob("*.txt")]
print(f"Full paths: {full_paths}")
# 8. Practical use: Process all files of a certain type
def process_all_csv_files():
"""Process all CSV files in the current directory"""
csv_files = glob.glob("*.csv")
for csv_file in csv_files:
print(f"Processing: {csv_file}")
# Read and process the file here
process_all_csv_files()
# 9. Comparing os.listdir() and glob
# os.listdir() - gives everything, you filter manually
# glob - gives you matching files directly
glob key points:
- Wildcards — use * for any characters, ? for one character
- Returns list — matching filenames as strings
- More readable — pattern matching is clear and concise
- Recursive option — search subdirectories
Quick Check: What wildcard matches any number of characters? (Answer: *)
Exploring Subdirectories with os.walk()
Going Deeper into Folders
# os.walk() lets you explore entire directory trees
import os
# Create a nested directory structure
os.makedirs("project/src", exist_ok=True)
os.makedirs("project/tests", exist_ok=True)
os.makedirs("project/data", exist_ok=True)
with open("project/src/main.py", "w") as f:
f.write("print('Hello from main')")
with open("project/tests/test.py", "w") as f:
f.write("print('Hello from tests')")
with open("project/data/data.txt", "w") as f:
f.write("Sample data")
# 1. Walk through all directories
def list_all_files(root_dir):
"""List all files in a directory and its subdirectories"""
print(f"Exploring: {root_dir}")
print("-" * 40)
for root, dirs, files in os.walk(root_dir):
print(f"\nDirectory: {root}")
print(f" Subdirectories: {len(dirs)}")
print(f" Files: {len(files)}")
for file in files:
print(f" {file}")
list_all_files("project")
# 2. Find all Python files in a project
def find_python_files(root_dir):
"""Find all .py files in a project structure"""
python_files = []
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.endswith(".py"):
full_path = os.path.join(root, file)
python_files.append(full_path)
return python_files
py_files = find_python_files("project")
print(f"\nPython files: {py_files}")
# 3. Count files by extension
def count_files_by_extension(root_dir):
"""Count files by their extension"""
extension_counts = {}
for root, dirs, files in os.walk(root_dir):
for file in files:
_, ext = os.path.splitext(file)
if ext:
extension_counts[ext] = extension_counts.get(ext, 0) + 1
return extension_counts
counts = count_files_by_extension("project")
print(f"\nFile counts by extension: {counts}")
# 4. Process files in subdirectories
def process_all_files(root_dir):
"""Process every file in the directory tree"""
total_files = 0
total_size = 0
for root, dirs, files in os.walk(root_dir):
for file in files:
full_path = os.path.join(root, file)
total_files += 1
total_size += os.path.getsize(full_path)
print(f"\nTotal files: {total_files}")
print(f"Total size: {total_size} bytes")
process_all_files("project")
os.walk() key points:
- Recursive — goes through all subdirectories
- Returns three values — root path, directories, files
- Efficient — doesn't load everything into memory
- Great for projects — exploring codebases and file systems
Quick Check: What does os.walk() return? (Answer: A generator of (root, dirs, files) tuples)
Getting File Information
Knowing More About Your Files
# Once you have files, you often want to know more about them
import os
import time
# 1. Getting file size
def get_file_size(filename):
"""Get the size of a file in bytes"""
try:
return os.path.getsize(filename)
except OSError:
return None
print(f"Size of file1.txt: {get_file_size('file1.txt')} bytes")
# 2. Getting file modification time
def get_file_modified_time(filename):
"""Get the last modified time of a file"""
try:
timestamp = os.path.getmtime(filename)
return time.ctime(timestamp)
except OSError:
return None
print(f"Last modified: {get_file_modified_time('file1.txt')}")
# 3. Getting file creation time (platform dependent)
def get_file_created_time(filename):
"""Get the creation time of a file (if available)"""
try:
timestamp = os.path.getctime(filename)
return time.ctime(timestamp)
except OSError:
return None
# 4. Get complete file info
def get_file_info(filename):
"""Get all available information about a file"""
try:
stat = os.stat(filename)
return {
"name": filename,
"size": stat.st_size,
"modified": time.ctime(stat.st_mtime),
"created": time.ctime(stat.st_ctime),
"is_file": os.path.isfile(filename),
"is_dir": os.path.isdir(filename),
"permissions": oct(stat.st_mode),
}
except OSError:
return None
# 5. Display info for all files
def list_files_with_info(directory="."):
"""List all files with their information"""
print(f"{'File name':<20} {'Size':<10} {'Modified':<25}")
print("-" * 55)
for item in os.listdir(directory):
full_path = os.path.join(directory, item)
if os.path.isfile(full_path):
size = os.path.getsize(full_path)
modified = time.ctime(os.path.getmtime(full_path))
print(f"{item:<20} {size:<10} {modified:<25}")
list_files_with_info()
File information key points:
- os.path.getsize() — file size in bytes
- os.path.getmtime() — last modified time
- os.stat() — complete file metadata
- time.ctime() — convert timestamp to readable format
Quick Check: How do you get a file's size? (Answer: os.path.getsize())
Handling Directory Errors
Dealing with Missing or Unreadable Directories
# Not every directory exists or is readable
import os
# 1. Safely list a directory
def safe_list_directory(directory):
"""List a directory safely with error handling"""
try:
items = os.listdir(directory)
print(f"Found {len(items)} items in '{directory}'")
return items
except FileNotFoundError:
print(f"Directory '{directory}' does not exist")
return []
except PermissionError:
print(f"Permission denied for '{directory}'")
return []
except NotADirectoryError:
print(f"'{directory}' is not a directory")
return []
except Exception as e:
print(f"Error listing '{directory}': {e}")
return []
# 2. Check if a directory exists before listing
def list_directory_if_exists(directory):
"""List directory only if it exists"""
if not os.path.exists(directory):
print(f"Directory '{directory}' does not exist")
return []
if not os.path.isdir(directory):
print(f"'{directory}' is not a directory")
return []
return os.listdir(directory)
# 3. Safe walk through directories
def safe_walk(directory):
"""Walk through a directory with error handling"""
try:
for root, dirs, files in os.walk(directory):
yield root, dirs, files
except PermissionError:
print(f"Permission denied walking '{directory}'")
except Exception as e:
print(f"Error walking '{directory}': {e}")
# 4. Getting file info with error handling
def safe_file_info(filename):
"""Get file info safely"""
try:
return {
"exists": os.path.exists(filename),
"is_file": os.path.isfile(filename),
"size": os.path.getsize(filename) if os.path.isfile(filename) else None,
"modified": time.ctime(os.path.getmtime(filename)) if os.path.exists(filename) else None,
}
except Exception as e:
return {"error": str(e)}
Error handling key points:
- FileNotFoundError — directory doesn't exist
- PermissionError — can't read the directory
- NotADirectoryError — path is not a directory
- Always check — existence and permissions before listing
Quick Check: What happens if you try to list a directory that doesn't exist? (Answer: Raises FileNotFoundError)
Best Practices for Listing Files
Professional Directory Listing Guidelines
# Best practices for listing files and directories
import os
import glob
# 1. Use the right tool for the job
# For simple listing: os.listdir()
# For pattern matching: glob.glob()
# For recursion: os.walk()
# 2. Always use full paths when needed
def list_with_full_paths(directory):
"""List files with full paths for safety"""
full_paths = []
for item in os.listdir(directory):
full_paths.append(os.path.join(directory, item))
return full_paths
# 3. Filter early, filter often
def get_python_files(directory):
"""Get all Python files efficiently"""
return [f for f in os.listdir(directory) if f.endswith(".py")]
# 4. Use constants for directories
DATA_DIR = "data"
LOG_DIR = "logs"
OUTPUT_DIR = "output"
# Instead of hardcoding:
# data_files = os.listdir("data")
# 5. Handle hidden files appropriately
def list_files_without_hidden(directory):
"""List files excluding hidden files (starting with .)"""
return [f for f in os.listdir(directory) if not f.startswith(".")]
# 6. Sort listings for consistency
files = sorted(os.listdir("."))
# 7. Use os.scandir() for large directories (Python 3.5+)
# os.scandir() is more efficient than os.listdir() for large directories
def list_with_scandir(directory):
"""List files using scandir for better performance"""
with os.scandir(directory) as entries:
return [entry.name for entry in entries if entry.is_file()]
# 8. Be mindful of performance
# For directories with thousands of files:
# - Use os.scandir() instead of os.listdir()
# - Process files in batches
# - Don't load everything into memory
Best practices summary:
- Right tool — choose appropriate method for your needs
- Full paths — avoid ambiguity by using full paths
- Filter early — reduce data as soon as possible
- Use constants — avoid hardcoded paths
- Handle hidden files — decide whether to include them
- Sort results — ensure consistent output
- Performance matters — use scandir for large directories
Quick Check: What is more efficient for large directories: os.listdir() or os.scandir()? (Answer: os.scandir())
Try It Yourself
Experiment with listing files in the editor below. Try different methods and see what you find.
LIST FILES PRACTICE
========================================
1. CREATING SAMPLE FILES
Sample files created: doc1.txt, doc2.txt, data.csv
2. OS.LISTDIR() - BASIC LISTING
Items in directory: ['doc1.txt', 'doc2.txt', 'data.csv']
3. FILTERING BY EXTENSION
Text files: ['doc1.txt', 'doc2.txt']
CSV files: ['data.csv']
4. GLOB - PATTERN MATCHING
All text files: ['doc1.txt', 'doc2.txt']
All CSV files: ['data.csv']
5. FILE INFORMATION
doc1.txt: 11 bytes
doc2.txt: 11 bytes
List files practice complete!
You've Got It!
You now know how to list files in directories, filter them by name or type, and explore subdirectories. These skills are essential for organizing and processing files.
Quick Quiz
Test what you've learned:
Frequently Asked Questions
What is the difference between os.listdir() and glob.glob()?
How do I list only files, not directories?
files = [f for f in os.listdir(".") if os.path.isfile(f)].
How do I list all files in a directory and its subdirectories?
os.walk() to traverse the directory tree. For example: for root, dirs, files in os.walk("."): for file in files: print(os.path.join(root, file)).
What's a common interview question about listing files?
How do I get file sizes while listing files?
os.path.getsize() for each file: for file in os.listdir("."): size = os.path.getsize(file). Be careful with directories — check if it's a file first.
What is os.scandir() and why is it useful?
os.scandir() returns an iterator of directory entries, which is more efficient than os.listdir() when you need file information. It's particularly useful for large directories where you need to check file types or sizes.
Where to Go From Here
Now that you can list files in directories, check out these related topics:
Binary Files
Learn how to read and write binary files.
Learn More →Zipping and Unzipping Files
Learn how to compress and extract files.
Learn More →📝 Assignments
Practice what you've learned with assignments.
Learn More →