Normalize CSV Column Names to snake_case in Python
Convert CSV header names to snake_case using a regular expression and write the updated file in place.
Python code
32 linesimport csv
import re
import sys
def to_snake_case(header):
header = re.sub(r"(?<=[a-z0-9])(?=[A-Z])", "_", header)
header = re.sub(r"[^a-zA-Z0-9]+", "_", header).strip("_").lower()
return header
def normalize_csv_headers(input_path, output_path=None):
with open(input_path, newline="", encoding="utf-8") as f:
reader = csv.reader(f)
rows = list(reader)
if not rows:
return
normalized = [to_snake_case(col) for col in rows[0]]
rows[0] = normalized
output = output_path or input_path
with open(output, "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(rows)
print("Normalized headers:", normalized)
if __name__ == "__main__":
normalize_csv_headers("example.csv")
Output
Normalized headers: ['id', 'first_name', 'last_name', 'email', 'created_at']
How it works
The to_snake_case function uses two regex substitutions. The first inserts an underscore between a lowercase letter/digit and an uppercase letter to handle camelCase. The second replaces any sequence of non-alphanumeric characters with an underscore, then strips leading/trailing underscores and lowercases everything. Reading the entire file into a list of rows with csv.reader allows easy header mutation before writing back. Writing to the same path overwrites the original file, and printing the normalized list confirms the change.
Common mistakes
- Forgetting to strip underscores after substitution, leaving headers like '_first_name_'.
- Not handling files with no header row, causing the function to silently skip or error.
- Assuming all headers are simple ASCII; accented characters get stripped by the regex.
Variations
- Use `csv.DictReader` and `csv.DictWriter` to convert headers while streaming rows.
- Write to a new file instead of overwriting to preserve the original.
Real-world use cases
- Preparing messy CSV exports from legacy systems for ingestion into a database schema that enforces snake_case naming.
- Normalizing column names from a user-uploaded CSV file before performing data analysis in pandas.
- Standardizing headers across multiple CSV files before merging them into a single dataset.
Sponsored
More from Files & data
- Append a Line to a Log File in Python easy
- Audit File Permissions Across a Project in Python easy
- Automatically Detect Corrupted Files Using SHA-256 Checksums in Python easy
- Automatically Highlight Data Validation Errors Inside Excel Files in Python easy
- Build a Command-Line To-Do List Application with Data Persistence in Python easy
- Build a File Index by Relative Path Hash Map in Python easy
Keep learning
Related tutorials and quizzes for this topic.