The csv module handles CSV files correctly—quoting, escaping, and edge cases that break naive string splitting.
Reading CSV
import csv
with open('data.csv', 'r', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row) # List of values
# data.csv:
# name,age,city
# Alice,30,New York
# Bob,25,"Los Angeles"
# Output:
# ['name', 'age', 'city']
# ['Alice', '30', 'New York']
# ['Bob', '25', 'Los Angeles']Writing CSV
import csv
rows = [
['name', 'age', 'city'],
['Alice', 30, 'New York'],
['Bob', 25, 'Los Angeles'],
]
with open('output.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerows(rows)
# Or one at a time
writer.writerow(['Charlie', 35, 'Chicago'])Always use newline='' to prevent blank line issues on Windows.
DictReader: Named Columns
import csv
with open('data.csv', 'r', newline='') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['age'])
# First row becomes field names by default
# row is a dict: {'name': 'Alice', 'age': '30', 'city': 'New York'}Custom field names:
reader = csv.DictReader(f, fieldnames=['first', 'second', 'third'])DictWriter: Write from Dicts
import csv
users = [
{'name': 'Alice', 'age': 30, 'city': 'New York'},
{'name': 'Bob', 'age': 25, 'city': 'Los Angeles'},
]
with open('output.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['name', 'age', 'city'])
writer.writeheader() # Write column names
writer.writerows(users)Custom Delimiters
import csv
# Tab-separated (TSV)
with open('data.tsv', 'r', newline='') as f:
reader = csv.reader(f, delimiter='\t')
# Semicolon-separated (European Excel)
with open('data.csv', 'r', newline='') as f:
reader = csv.reader(f, delimiter=';')
# Pipe-separated
reader = csv.reader(f, delimiter='|')Quoting Options
import csv
# Quote all fields
writer = csv.writer(f, quoting=csv.QUOTE_ALL)
# Quote only non-numeric
writer = csv.writer(f, quoting=csv.QUOTE_NONNUMERIC)
# Minimal quoting (default)
writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
# No quoting
writer = csv.writer(f, quoting=csv.QUOTE_NONE, escapechar='\\')Handling Edge Cases
Fields with Commas
# Automatically quoted
data = [['name', 'address'], ['Alice', '123 Main St, Apt 4']]
writer.writerows(data)
# Output: name,address
# Alice,"123 Main St, Apt 4"Fields with Quotes
data = [['quote', 'value'], ['He said "hello"', 'test']]
writer.writerows(data)
# Output: quote,value
# "He said ""hello""",testNewlines in Fields
data = [['text'], ['Line 1\nLine 2']]
writer.writerows(data)
# Output: text
# "Line 1
# Line 2"Reading from Strings
import csv
import io
csv_string = """name,age
Alice,30
Bob,25"""
reader = csv.reader(io.StringIO(csv_string))
for row in reader:
print(row)Custom Dialects
import csv
# Register a custom dialect
csv.register_dialect('pipes', delimiter='|', quoting=csv.QUOTE_MINIMAL)
with open('data.txt', 'r') as f:
reader = csv.reader(f, dialect='pipes')
# Built-in dialects
csv.reader(f, dialect='excel') # Standard CSV
csv.reader(f, dialect='excel-tab') # TSV
csv.reader(f, dialect='unix') # Unix-stylePractical Examples
Convert Types
import csv
with open('numbers.csv', 'r', newline='') as f:
reader = csv.reader(f)
next(reader) # Skip header
for row in reader:
name, age, salary = row
age = int(age)
salary = float(salary)
print(f"{name}: {age} years, ${salary:,.2f}")Filter and Transform
import csv
with open('input.csv', 'r', newline='') as infile:
with open('output.csv', 'w', newline='') as outfile:
reader = csv.DictReader(infile)
writer = csv.DictWriter(outfile, fieldnames=['name', 'age'])
writer.writeheader()
for row in reader:
if int(row['age']) >= 18:
writer.writerow({
'name': row['name'].upper(),
'age': row['age']
})Append to CSV
import csv
new_row = ['Charlie', 35, 'Chicago']
with open('data.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow(new_row)CSV to JSON
import csv
import json
with open('data.csv', 'r', newline='') as f:
reader = csv.DictReader(f)
data = list(reader)
with open('data.json', 'w') as f:
json.dump(data, f, indent=2)Quick Reference
import csv
# Read
reader = csv.reader(file)
reader = csv.DictReader(file)
# Write
writer = csv.writer(file)
writer = csv.DictWriter(file, fieldnames=['a', 'b'])
writer.writeheader() # DictWriter only
writer.writerow(row)
writer.writerows(rows)
# Options
csv.reader(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)| Quoting Constant | Behavior |
|---|---|
QUOTE_MINIMAL | Quote only when needed |
QUOTE_ALL | Quote everything |
QUOTE_NONNUMERIC | Quote non-numbers |
QUOTE_NONE | Never quote (use escapechar) |
Don't parse CSV by hand with split(','). The csv module handles all the edge cases you'll inevitably hit.
React to this post: