File I/O & CSV/JSON

Difficulty: Beginner

Question

How do you read and write files in Python? How do you handle CSV and JSON?

Answer

Python provides built-in functions for file I/O and modules for structured data formats.

File modes: 'r' (read), 'w' (write/overwrite), 'a' (append), 'x' (create/fail if exists), 'b' (binary).

Always use 'with' statement for file operations to ensure proper cleanup.

For structured data: - json module: serialize/deserialize JSON - csv module: read/write CSV files - pathlib: modern, object-oriented file path handling (preferred over os.path)

Code examples

Reading and Writing Files

# Writing a file
with open('example.txt', 'w') as f:
    f.write('Line 1\n')
    f.write('Line 2\n')
    f.writelines(['Line 3\n', 'Line 4\n'])

# Reading entire file
with open('example.txt', 'r') as f:
    content = f.read()
    print(content)

# Reading line by line (memory efficient for large files)
with open('example.txt') as f:
    for line in f:  # f is an iterator
        print(line.strip())

# Reading into a list
with open('example.txt') as f:
    lines = f.readlines()  # List of lines
    print(lines)

# Using pathlib (modern approach)
from pathlib import Path

p = Path('example.txt')
p.write_text('Hello from pathlib!')
content = p.read_text()
print(content)
print(p.exists())       # True
print(p.suffix)         # '.txt'
print(p.stem)           # 'example'
print(p.parent)         # '.' (current dir)

Iterating over a file object reads line by line without loading the entire file. pathlib provides a cleaner API than os.path for file operations.

JSON: Read, Write, and Transform

import json

# Python dict to JSON string
data = {
    'name': 'Alice',
    'age': 30,
    'languages': ['Python', 'JavaScript'],
    'active': True,
    'address': None
}

# Serialize to JSON string
json_str = json.dumps(data, indent=2)
print(json_str)

# Deserialize from JSON string
parsed = json.loads(json_str)
print(parsed['name'])  # 'Alice'
print(type(parsed))   # <class 'dict'>

# Write to JSON file
with open('data.json', 'w') as f:
    json.dump(data, f, indent=2)

# Read from JSON file
with open('data.json') as f:
    loaded = json.load(f)
    print(loaded == data)  # True

# Custom serialization
from datetime import datetime

class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

event = {'name': 'Meeting', 'date': datetime.now()}
print(json.dumps(event, cls=DateEncoder, indent=2))

json.dumps/loads work with strings, json.dump/load work with files. Custom JSONEncoder handles non-serializable types like datetime.

CSV: Read and Write

import csv

# Write CSV
headers = ['name', 'age', 'city']
rows = [
    ['Alice', 30, 'New York'],
    ['Bob', 25, 'London'],
    ['Charlie', 35, 'Paris']
]

with open('people.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(headers)
    writer.writerows(rows)

# Read CSV
with open('people.csv', newline='') as f:
    reader = csv.reader(f)
    header = next(reader)  # Skip header
    for row in reader:
        print(f"{row[0]} is {row[1]} from {row[2]}")

# DictReader/DictWriter (more readable)
with open('people.csv', newline='') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['name']}: {row['city']}")

# Write with DictWriter
with open('output.csv', 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=['name', 'score'])
    writer.writeheader()
    writer.writerow({'name': 'Alice', 'score': 95})
    writer.writerow({'name': 'Bob', 'score': 87})

DictReader maps each row to a dict with column headers as keys. Always pass newline='' to open() when using the csv module to avoid blank lines.

Key points

Concepts covered

File Reading, File Writing, CSV, JSON, pathlib