Python CSV Module Tutorial: Read, Write & Manipulate CSV Files (2026)
Python’s built-in csv module and pandas are the standard ways to read and write CSV in Python. This guide covers both: reading/writing with csv.reader and csv.writer, DictReader/DictWriter, and pandas read_csv/to_csv. We also compare performance and when to use which. For quick checks without code, use neatcsv’s CSV Validator and CSV Cleaner.
Table of Contents
CSV is plain text with rows and columns; Python’s csv module handles RFC 4180-style quoting and delimiters. For structure basics, see What is a CSV File? and for the JS side Parse CSV in JavaScript.
1. Why Use Python for CSV?
Python is widely used for data pipelines, ETL, and analytics. The standard library csv module requires no extra dependencies and works well for simple read/write and streaming. pandas adds powerful filtering, grouping, and transformation—ideal when you need to analyze or clean data. For one-off validation or cleaning in the browser, CSV Validator and Clean CSV from neatcsv are handy.
2. csv Module: Reading
Open the file in text mode (and specify encoding) and pass the file object to csv.reader. Each iteration yields a list of strings (one per column).
import csv
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row) # ['name', 'email'] then ['Alice', 'alice@example.com'], ...
Use csv.reader(f, delimiter=';') for semicolon-separated files, or delimiter='\t' for TSV. The first row is not automatically treated as headers—you can skip it or use it as column names.
3. csv Module: Writing
Use csv.writer and writerow/writerows. The module escapes commas and quotes automatically.
import csv
rows = [
['name', 'email'],
['Alice', 'alice@example.com'],
['Bob', 'bob@example.com']
]
with open('out.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerows(rows)
Always use newline='' when writing CSV on Windows to avoid extra blank lines. On other platforms it doesn’t hurt.
4. DictReader and DictWriter
csv.DictReader uses the first row as keys and yields dictionaries per row. csv.DictWriter writes rows from dicts when you pass fieldnames.
import csv
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['email'])
# Writing
fieldnames = ['name', 'email']
with open('out.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'name': 'Alice', 'email': 'alice@example.com'})
5. pandas: read_csv and to_csv
Install pandas: pip install pandas. read_csv returns a DataFrame; the first row is used as column names by default.
import pandas as pd
df = pd.read_csv('data.csv', encoding='utf-8')
# Custom delimiter: pd.read_csv('data.csv', sep=';')
# No header: pd.read_csv('data.csv', header=None)
# Inspect
print(df.head())
print(df.columns)
# Write back
df.to_csv('out.csv', index=False, encoding='utf-8')
Use index=False in to_csv to avoid writing the DataFrame index as an extra column. For cleaning (trim, dedupe, normalize), you can combine pandas with our Clean CSV tool for quick pre-checks.
6. csv vs pandas: When to Use Which
Use the csv module when: you want no dependencies, you stream large files row-by-row, or you only need simple read/write. Use pandas when: you need filtering, grouping, merging, or analytics; you’re already in a Jupyter notebook or data script. For very large files (e.g. millions of rows), csv is memory-efficient (one row at a time); pandas can use chunksize in read_csv to avoid loading everything at once.
7. Encoding and Edge Cases
Always pass encoding='utf-8' when opening files (or encoding='utf-8-sig' to strip a BOM). For legacy files, try latin-1 or cp1252. See CSV Encoding Explained for details. Quoted fields with commas and newlines are handled correctly by both csv and pandas. If you get inconsistent columns or odd characters, validate the file first with neatcsv’s CSV Validator.
8. Summary
Use Python’s csv module for dependency-free, streaming-friendly read/write; use DictReader/DictWriter for row-as-dict. Use pandas when you need analysis and transformation. Set encoding='utf-8' and newline='' when writing. For quick validation and cleaning without code, use CSV Validator and Clean CSV from neatcsv.