Of course! In Python, there are several ways to get a list of files and directories. The best method depends on what you need to do (e.g., list files in the current directory, list files recursively, filter by extension, etc.).

Here is a comprehensive guide, starting with the most common and recommended approach.
The Modern & Recommended Way: pathlib (Python 3.4+)
The pathlib module is an object-oriented filesystem path library. It's generally considered more readable, less error-prone, and more powerful than the older os module for path manipulations.
Basic Example: List Files in the Current Directory
This code lists all entries (files and directories) in the current directory.
from pathlib import Path
# Get the current working directory
current_dir = Path.cwd()
# List all entries (files and directories) in the current directory
entries = list(current_dir.iterdir())
for entry in entries:
# entry is a Path object
print(entry.name)
Output:
my_document.txt
another_folder
image.png
script.py
Filtering for Files Only
Often, you only want files, not directories.
from pathlib import Path
current_dir = Path.cwd())
# Use a list comprehension to get only files
files = [entry for entry in current_dir.iterdir() if entry.is_file()]
for file in files:
print(file.name)
Output:
my_document.txt
image.png
script.py
Filtering by File Extension
A very common task is to find all files with a specific extension.
from pathlib import Path
current_dir = Path.cwd()
# Find all .txt files
txt_files = list(current_dir.glob('*.txt'))
for file in txt_files:
print(file.name)
Output:
my_document.txt
The glob('*.txt') method is very powerful. It uses Unix shell-style wildcards.
Listing Files Recursively (in Subdirectories)
To get a list of all files in a directory and all its subdirectories, use rglob().
from pathlib import Path
# Use '.' to start from the current directory
# Use Path.home() to start from your home directory
# Use Path('/path/to/start') for any other path
root_dir = Path('.')
# rglob('*') means "recursive glob for everything"
all_files = list(root_dir.rglob('*'))
for file in all_files:
# We can filter for files here too
if file.is_file():
print(file)
Output:
my_document.txt
image.png
script.py
another_folder/notes.txt
another_folder/report.pdf
The Classic Way: os and os.path
The os module is the traditional way to interact with the operating system. It's still very common and works in all versions of Python.
Basic Example: List Files in the Current Directory
import os
# Get a list of all entries in the current directory
entries = os.listdir()
for entry in entries:
print(entry)
Filtering for Files Only
You need to combine os.listdir() with os.path.isfile().
import os
entries = os.listdir()
files = [entry for entry in entries if os.path.isfile(entry)]
for file in files:
print(file)
Filtering by File Extension
This requires a bit more manual string manipulation.
import os
entries = os.listdir()
txt_files = [entry for entry in entries if entry.endswith('.txt')]
for file in txt_files:
print(file)
Listing Files Recursively
For recursive listing, os.walk() is the perfect tool. It's a generator that yields a tuple for each directory it visits.
import os
# os.walk() is a generator, so we loop through it
for root, dirs, files in os.walk('.'):
# 'root' is the string path to the current directory
# 'dirs' is a list of subdirectories in 'root'
# 'files' is a list of files in 'root'
print(f"--- Looking in: {root} ---")
for file in files:
# os.path.join is the correct way to build paths
full_path = os.path.join(root, file)
print(full_path)
Output:
--- Looking in: . ---
./my_document.txt
./image.png
./script.py
--- Looking in: ./another_folder ---
./another_folder/notes.txt
./another_folder/report.pdf
Advanced Example: Getting a List of File Paths with Metadata
Often, you don't just need the file names, but also their full paths, sizes, modification times, etc. pathlib makes this very clean.
from pathlib import Path
import datetime
def get_file_info(directory):
"""Returns a list of dictionaries with file info."""
file_info_list = []
directory = Path(directory)
for item in directory.rglob('*'):
if item.is_file():
info = {
'path': item,
'name': item.name,
'size_bytes': item.stat().st_size,
'size_mb': round(item.stat().st_size / (1024 * 1024), 2),
'modified': datetime.datetime.fromtimestamp(item.stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S')
}
file_info_list.append(info)
return file_info_list
# --- Usage ---
files_data = get_file_info('.')
for file_data in files_data:
print(f"File: {file_data['name']}")
print(f" Path: {file_data['path']}")
print(f" Size: {file_data['size_mb']} MB")
print(f" Modified: {file_data['modified']}")
print("-" * 20)
Summary: Which one should you use?
| Task | pathlib (Recommended) |
os (Classic) |
|---|---|---|
| List files in one directory | Path.cwd().iterdir() |
os.listdir() |
| Filter for files | [p for p in dir.iterdir() if p.is_file()] |
[f for f in os.listdir() if os.path.isfile(f)] |
| Filter by extension | dir.glob('*.txt') |
[f for f in os.listdir() if f.endswith('.txt')] |
| List files recursively | dir.rglob('*') |
os.walk('.') |
| Join paths | Path('folder') / 'file.txt' |
os.path.join('folder', 'file.txt') |
| Get file stats | path.stat() |
os.stat(path) |
Recommendation: If you are using Python 3.4 or newer, prefer pathlib. It's more intuitive, less error-prone with slashes ( vs \), and its object-oriented style is often easier to read and maintain. Use os if you're working with older codebases or older Python versions.
