CSV (comma-separated values) is one of the most common formats for exchanging tabular data — spreadsheets, exported reports, and simple databases all tend to pass through a CSV file at some point. Python's built-in csv module handles the fiddly parts (quoting, commas inside values, line endings) so you don't have to split strings by hand.

Write Rows to a CSV File

import csv

rows = [
    ["Name", "Age", "City"],
    ["Alice", 28, "New York"],
    ["Bob", 34, "Chicago"],
    ["Charlie", 22, "Austin"],
]

with open("people.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerows(rows)

print("people.csv written successfully")

Output:

people.csv written successfully

Read Rows Back from a CSV File

import csv

with open("people.csv", "r", newline="") as file:
    reader = csv.reader(file)
    header = next(reader)          # grab the header row separately
    print(f"Columns: {header}")
    for row in reader:
        print(row)

Output:

Columns: ['Name', 'Age', 'City']
['Alice', '28', 'New York']
['Bob', '34', 'Chicago']
['Charlie', '22', 'Austin']

The with open(...) context manager is doing important work here: it guarantees the file gets closed automatically — even if an error happens partway through reading or writing — without you needing a separate file.close() call. The newline="" argument matters specifically for CSV: without it, Windows can insert extra blank lines between rows because of how it handles line endings.

Notice that every value read back from the CSV comes out as a string — '28', not the integer 28 you originally wrote. CSV is a plain text format with no concept of data types, so if you need numbers back, you have to convert them yourself, e.g. int(row[1]).

For real-world data with column headers, csv.DictReader and csv.DictWriter are usually more convenient — they let you access each row as a dictionary keyed by column name (e.g. row["Name"]) instead of a plain list indexed by position.