A CSV (comma-separated values) file stores a table as plain text: one row per line, with the values in each row separated by commas. CSV files open in Excel and Google Sheets, and many tools export data in this format. Python has a built-in csv module that reads and writes them correctly. This lesson shows how to write rows, read rows, use headers with DictReader and DictWriter, append data, and avoid the common mistakes, with output for every example.

Run these examples on your own computer. An online compiler may block or reset files. If you are new to files, read our lesson on file handling first.

 

What does a CSV file look like?

name,marks
Asha,85
Ravi,72
Meena,91

The first line is usually the header, with the column names. Each of the other lines is a record.

 

Write a CSV file

Open the file in write mode with newline=” and use csv.writer().

import csv

rows = [['name', 'marks'], ['Asha', 85], ['Ravi', 72], ['Meena', 91]]

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

print(open('students.csv').read())

Output:

name,marks
Asha,85
Ravi,72
Meena,91

writerow() writes one row, and writerows() writes a list of rows. The newline=” option is important. Without it, files written on Windows can get an empty line after every row, because the csv module handles the line endings itself.

 

Read a CSV file

Use csv.reader(). Each row comes back as a list of strings.

import csv

with open('students.csv', newline='') as f:
    for row in csv.reader(f):
        print(row)

Output:

['name', 'marks']
['Asha', '85']
['Ravi', '72']
['Meena', '91']

Notice that the marks are strings (’85’), not numbers. Convert them with int() or float() when you need to calculate.

Skip the header and calculate

next() reads one row from the reader, so you can use it to skip the header.

import csv

with open('students.csv', newline='') as f:
    reader = csv.reader(f)
    header = next(reader)
    print(header)

    total = 0
    count = 0
    for row in reader:
        total += int(row[1])
        count += 1

    print(round(total / count, 2))

Output:

['name', 'marks']
82.67

Append rows

Use mode ‘a’ to add rows to the end of the file.

import csv

with open('students.csv', 'a', newline='') as f:
    csv.writer(f).writerow(['Kiran', 66])

The file now has a fourth student.

 

Read rows as dictionaries: DictReader

csv.DictReader() uses the header row as the keys, so you can use column names instead of numbers.

import csv

with open('students.csv', newline='') as f:
    for row in csv.DictReader(f):
        print(row['name'], row['marks'])

Output:

Asha 85
Ravi 72
Meena 91
Kiran 66

This code is easier to read than row[0] and row[1], and it keeps working if the columns move.

Filter rows

import csv

with open('students.csv', newline='') as f:
    top = [r['name'] for r in csv.DictReader(f) if int(r['marks']) > 70]

print(top)
['Asha', 'Ravi', 'Meena']

Write rows from dictionaries: DictWriter

Give DictWriter the column names, write the header with writeheader(), and then write each row as a dictionary.

import csv

with open('people.csv', 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=['name', 'city'])
    writer.writeheader()
    writer.writerow({'name': 'Asha', 'city': 'Pune'})
    writer.writerow({'name': 'Ravi', 'city': 'Nashik'})

print(open('people.csv').read())

Output:

name,city
Asha,Pune
Ravi,Nashik

Other separators and quotes

Some files use a semicolon or a tab instead of a comma. Set the delimiter:

import csv

with open('semi.csv', 'w', newline='') as f:
    csv.writer(f, delimiter=';').writerow(['a', 'b'])

print(open('semi.csv').read())
a;b

If a value contains a comma, the csv module puts it in quotes for you, so the row does not break:

import csv

with open('quote.csv', 'w', newline='') as f:
    csv.writer(f).writerow(['Smith, John', 'x'])

print(open('quote.csv').read())
"Smith, John",x

This is why you should use the csv module, and not split lines on commas yourself. A simple split would cut ‘Smith, John’ into two values.

 

Quick reference

Task

Code

Write rows

csv.writer(f).writerows(rows)

Read rows as lists

csv.reader(f)

Skip the header

next(reader)

Read rows as dictionaries

csv.DictReader(f)

Write rows from dictionaries

csv.DictWriter(f, fieldnames=[…])

Another separator

csv.reader(f, delimiter=’;’)

 

Common mistakes

  • Forgetting newline=” when you open the file. You may get blank lines between rows on Windows.
  • Treating the values as numbers. Everything you read is a string until you convert it.
  • Reading the header as data. Skip it with next(), or use DictReader.
  • Splitting lines with split(‘,’). It breaks on values that contain commas.
  • Using mode ‘w’ when you want to add rows. Mode ‘w’ erases the file. Use ‘a’.
  • Encoding problems. If your file has non-English characters, open it with encoding=’utf-8′.

 

Practice questions

  1. Write a CSV file with the columns name, age and city for five people.
  2. Read the file back, and print only the people who are older than 18.
  3. Find the highest marks in a CSV file of students.
  4. Add a new row to the file without erasing the old rows.
  5. Copy a CSV file to a new file, but write only the name column.

 

Summary

  • Use the csv module, and open files with newline=”.
  • csv.writer() and csv.reader() work with lists, and DictWriter and DictReader work with dictionaries.
  • Values are read as strings, so convert them to numbers when you need to.
  • Use mode ‘a’ to append, and next() to skip the header.