Beginner: data foundations · Python for data · topic 3 of 62 · 30 min
Reading CSV and JSON with the standard library
Explanation
Why these two formats
CSV means comma-separated values. It is a plain text file where each line is a row and commas separate the columns; the first line usually holds the column names (the header). Excel, Google Sheets, bank statements and government data portals can all export CSV. JSON (JavaScript Object Notation) is the format most web APIs use: it has objects in curly brackets and lists in square brackets, which map straight onto Python dicts and lists.
Text that behaves like a file
The csv module reads from a file. In the browser tasks there are no files, so we keep the CSV in a string and wrap it with io.StringIO, which makes a string behave like an open file. At work you would use open() on a real file instead; everything else stays the same.
csv.reader: rows as lists
import csv, io
text = """item,qty,price
milk,2,30
bread,1,45
rice,5,60
"""
for row in csv.reader(io.StringIO(text)):
print(row)
# ['item', 'qty', 'price']
# ['milk', '2', '30']
# ['bread', '1', '45']
# ['rice', '5', '60']csv.DictReader: rows as dicts
DictReader reads the header line for you and gives each row as a dict keyed by column name. That is exactly the list-of-dicts table from the previous topic, so it is usually the better choice.
rows = list(csv.DictReader(io.StringIO(text)))
print(rows[0]) # {'item': 'milk', 'qty': '2', 'price': '30'}
total = sum(int(r["qty"]) * int(r["price"]) for r in rows)
print(total) # 405Blanks and messy values
Real files have gaps. A blank cell arrives as an empty string "", and int("") raises a ValueError. Decide on purpose what a blank means: skip the row, count it as 0, or keep it as None (missing). For money and marks, None is usually the honest choice, because 0 is a real value. Module 4 goes deeper into handling missing data.
text = """name,city,salary
Asha,Pune,52000
Ravi,"Mumbai, MH",
Meena,Delhi,61000
"""
for r in csv.DictReader(io.StringIO(text)):
salary = int(r["salary"]) if r["salary"].strip() else None
print(r["name"], r["city"], salary)
# Asha Pune 52000
# Ravi Mumbai, MH None
# Meena Delhi 61000JSON: loads and dumps
json.loads (load string) turns JSON text into Python values: objects become dicts, arrays become lists, true and false become True and False, and null becomes None. json.dumps (dump string) goes the other way, which is how you send data to an API or save it.
import json
text = '{"city": "Pune", "orders": [250, 120], "paid": true, "coupon": null}'
data = json.loads(text)
print(data["orders"], sum(data["orders"])) # [250, 120] 370
print(data["paid"], data["coupon"]) # True None
print(json.dumps({"item": "chai", "price": 15})) # {"item": "chai", "price": 15}
print(json.dumps({"price": "₹250"})) # {"price": "\u20b9250"}
print(json.dumps({"price": "₹250"}, ensure_ascii=False)) # {"price": "₹250"}At work: real files and pandas
import csv
with open("sales.csv", newline="", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
import pandas as pd
df = pd.read_csv("sales.csv") # pandas also guesses number types for youCommon mistakes
- Doing maths on text: "30" + "45" gives "3045". Fix: convert with int() or float() as soon as you read the value.
- Splitting lines with split(","). It breaks on quoted values like "Mumbai, MH". Fix: always use the csv module.
- Crashing on blanks with int(""). Fix: check value.strip() first and use None (or skip the row) on purpose.
- Mixing up loads and load. Fix: loads and dumps work with strings; load and dump work with open files.
- Writing JSON by hand with single quotes. JSON needs double quotes, so {'a': 1} is not valid JSON. Fix: build a dict and call json.dumps.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Reading CSV and JSON with the standard library · 1/7
In this lesson you will read the two most common data formats, CSV and JSON, using only Python's standard library.
Prefer a video by a teacher? Find free videos on “python csv DictReader json loads tutorial” on YouTube ↗
In real life: Rainfall data from a government portal
India's Open Government Data Platform (data.gov.in) publishes many datasets, such as rainfall by district, as CSV files you can download, and some through an API that returns JSON. A typical first step is to read the CSV, convert the rainfall column to numbers, skip blank months, and total by district. The values below are made-up sample numbers, not real rainfall.
import csv, io
text = """district,month,rain_mm
Pune,Jun,180.5
Pune,Jul,
Nashik,Jun,120.0
Nashik,Jul,210.25
"""
total = 0.0
for r in csv.DictReader(io.StringIO(text)):
if r["rain_mm"].strip():
total += float(r["rain_mm"])
print(round(total, 2))Practice (0/3 done)
Write parse_items(text) that reads CSV text with the header item,qty,price and returns a list of dicts in which "qty" and "price" are ints. Example row: {"item": "milk", "qty": 2, "price": 30}. Use csv.DictReader with io.StringIO.
Write column_total(text, column) that reads CSV text (with a header) and returns the total of the named column as a float rounded to 2 decimal places. Skip blank cells (empty or only spaces). If there are no numbers, return 0.0.
An API returns JSON text like {"orders": [{"id": 1, "amount": 250, "status": "paid"}, ...]}. Write total_paid(json_text) that returns the total amount of orders whose status is "paid". If there are no paid orders, return 0.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Counting and grouping: collections and statisticsPython for data · same module
- CSV files and simple statisticsPython Programming · Working with data
- pandas basics: Series and DataFramesCleaning, exploring and visualising data
- JSON and regular expressionsPython Programming · Errors, modules and the standard library
- Cleaning messy dataCleaning, exploring and visualising data
- JSON: the language of APIsBackend Development · How the web and backends work
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
A CSV row is read with csv.DictReader. What type is r["qty"] for the value 5?
Answer: str
The csv module never converts types. Every value is a string until you convert it.
Why not read CSV lines with line.split(",")?
Answer: Quoted values that contain commas, like "Mumbai, MH", get broken into two columns
The csv module understands quotes; a plain split does not.
What does json.loads('{"ok": true, "note": null}') give?
Answer: {'ok': True, 'note': None}
JSON true becomes Python True and null becomes None.
What does io.StringIO(text) do?
Answer: Makes a string behave like an open file
csv readers expect a file; StringIO wraps a string so it can be read like one.
A salary cell is blank. Which choice is usually most honest when you store it?
Answer: None, meaning missing
0 is a real salary and would drag the average down. None marks the value as missing so you can decide later, openly, how to handle it.
What does csv.DictReader give you for each row?Related
Answer: A dict with the header names as keys
DictReader uses the header row as keys, so you can write row["marks"].
You just loaded a new CSV. Which command shows each column's type and how many values are missing?Related
What does json.dumps(True) return?Related
Answer: "true"
JSON writes booleans in small letters, so you get the text true.
A date column has "05/01/2025" in Indian style. What should you do?Related
Answer: Pass format="%d/%m/%Y" explicitly
Guessing may read it as May 1. An explicit format avoids the mix-up.
From Cleaning messy data
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Python for data” before its exam: Counting and grouping: collections and statistics, Writing data code that others can trust.
- Module 1 exam: Python for data · 14 questions · 20 min, without help. 5 topics of this module still to finish first.
- Then the next module, Statistics made simple. 62 topics left in the course before the final exam.
← Previous: Python essentials for data: records, lists and dictionaries