I keep coming back to CSV files whenever I need to move data between systems. They are the simplest way to represent tabular data as plain text, and every system from databases to spreadsheets can read them. If you have been storing data in Excel and need something more portable, CSV is where most people end up.

This article covers how to write data into CSV files using Python’s built-in csv module. By the end, you will know how to use csv.writer and csv.DictWriter, handle headers, append data to existing files, and read the results back.

TLDR

  • Open files with open("file.csv", "w", newline="") to avoid blank rows on Windows
  • Use csv.writer for list-based data and writerow() or writerows() for writing
  • Use csv.DictWriter when data comes from dictionaries
  • Always call writeheader() with DictWriter to output column names first
  • Pass append mode "a" to write to an existing CSV without overwriting it

What is a CSV File in Python?

A CSV file stores tabular data as plain text where each value is separated by a comma. The first row typically contains column headers, and subsequent rows contain data records. Python ships with a built-in csv module that handles the formatting details, so you do not need to manually concatenate commas and newlines.

Writing CSV Files with csv.writer

The csv.writer class takes a file object and writes rows as lists. Each list becomes one row in the file. The writerow method writes a single row, and writerows writes multiple rows at once. The newline="" argument is required on Windows to prevent extra blank rows between records, as covered in the guide to handling ValueError when detecting strings and integers.


import csv

with open("student_results.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["Name", "English", "Math", "Science"])
    writer.writerow(["Varun", "91", "90", "74"])
    writer.writerow(["Rahul", "89", "94", "81"])
    writer.writerow(["Kabir", "80", "93", "88"])

The file opens once and closes automatically when the with block ends. The newline="" argument prevents blank rows on Windows, which is the most common gotcha when writing CSV files across operating systems.


Name,English,Math,Science
Varun,91,90,74
Rahul,89,94,81
Kabir,80,93,88

When all rows are ready at once, writerows() is cleaner than calling writerow() in a loop. The Python sum function works well for aggregating numeric columns before writing them to a CSV file.


import csv

data = [
    ["Name", "English", "Math", "Science"],
    ["Varun", "91", "90", "74"],
    ["Rahul", "89", "94", "81"],
    ["Kabir", "80", "93", "88"],
]

with open("student_results.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(data)

This produces the same output as the previous example. The data list contains the header row followed by all student records.


Name,English,Math,Science
Varun,91,90,74
Rahul,89,94,81
Kabir,80,93,88

Writing CSV Files with csv.DictWriter

When data lives in dictionaries, csv.DictWriter is a better fit. It maps dictionary keys to column names you specify upfront, so the order of keys in each dict does not matter. This approach pairs well with reading data from a text file you have parsed or from a JSON source.


import csv

students = [
    {"Name": "Varun", "English": "91", "Math": "90", "Science": "74"},
    {"Name": "Rahul", "English": "89", "Math": "94", "Science": "81"},
    {"Name": "Kabir", "English": "80", "Math": "93", "Science": "88"},
]

fieldnames = ["Name", "English", "Math", "Science"]

with open("student_results.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(students)

The writeheader() call outputs the column names as the first row. Then writerows() writes each dictionary as a row, matching keys to the fieldnames order you provided.


Name,English,Math,Science
Varun,91,90,74
Rahul,89,94,81
Kabir,80,93,88

Appending to an Existing CSV File

To add rows to an existing file without overwriting it, open the file in append mode "a" instead of write mode. The header gets written only if the file is new, so a common pattern checks whether the file already has content. This is useful when collecting data over time, similar to how you might append items to a Python array in memory.


import csv
import os

filename = "student_results.csv"
new_students = [
    {"Name": "Suman", "English": "92", "Math": "97", "Science": "94"},
]

file_exists = os.path.exists(filename)

with open(filename, "a", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["Name", "English", "Math", "Science"])
    if not file_exists:
        writer.writeheader()
    writer.writerows(new_students)

The os.path.exists check prevents duplicate headers if the file already has one. Each call to this script appends the new student to the end of the CSV.


Name,English,Math,Science
Varun,91,90,74
Rahul,89,94,81
Kabir,80,93,88
Suman,92,97,94

Reading a CSV File

For completeness, here is how to read the data back. The csv.reader object iterates over rows as lists, and csv.DictReader returns rows as dictionaries, which pairs naturally with the DictWriter approach. You can also use Python user input to collect values at runtime and write them to a CSV file.


import csv

with open("student_results.csv", newline="") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["Name"], row["Math"])

DictReader reads the header row automatically and uses those names as dictionary keys. The output shows each student’s name alongside their Math score.


Varun 90
Rahul 94
Kabir 93
Suman 97

FAQ

Q: Why does my CSV file have blank rows between each data row on Windows?

Opening the file with open("file.csv", "w") without the newline="" argument causes Python to write \\r\\n line endings, which creates blank rows on some Windows configurations. Always pass newline="" when opening CSV files in text mode.

Q: Should I use csv.writer or csv.DictWriter?

Use csv.writer when data is already in list or tuple format. Use csv.DictWriter when data comes from dictionaries or JSON, because it keeps column names explicit and makes the code easier to read.

Q: Can I write non-string values to a CSV file?

Yes, csv.writer converts numbers to their string representation automatically. Dates, booleans, and None all convert to readable string formats before being written.

Q: How do I write a CSV file with custom column order?

With csv.DictWriter, pass the desired column names as fieldnames in the order you want the columns to appear. With csv.writer, write rows as lists in that same order.

Share.
Leave A Reply