JSON & CSV
Plain text files are fine for simple lines, but real data has structure: a student has a name, a city and marks; an order has items and prices. Two text formats are used everywhere to store and exchange such data. JSON is the language of web APIs and settings files. CSV is the language of spreadsheets.
Python's standard library has a module for each: json and csv. In this lesson you will convert Python data to and from both formats and save it in files.
What JSON looks like
JSON (JavaScript Object Notation) is a text format that looks very much like Python dictionaries and lists. A weather API, a mobile app or a settings file might send you text like this:
{
"city": "Pune",
"temperature": 31.5,
"rain_expected": false,
"next_days": [30, 29, 33],
"alert": null
}JSON has fewer types than Python, so the json module translates between them:
| JSON | Python |
|---|---|
object {...} | dict |
array [...] | list |
string "..." | str |
number 42, 31.5 | int, float |
true / false | True / False |
null | None |
JSON strings always use double quotes, and keys must be strings.
Converting with dumps() and loads()
json.dumps() (dump to string) turns Python data into JSON text. json.loads() (load from string) does the opposite.
import json
order = {
"customer": "Isha",
"items": ["paneer roll", "lassi"],
"total": 240,
"paid": True,
"coupon": None,
}
text = json.dumps(order)
print(text)
print(type(text))
back = json.loads(text)
print(back["items"][0], back["paid"]){"customer": "Isha", "items": ["paneer roll", "lassi"], "total": 240, "paid": true, "coupon": null}
<class 'str'>
paneer roll TrueLook closely at the JSON text: True became true and None became null. When you load it back, they return to Python values.
Readable output and Indian text
By default dumps() writes everything on one line and replaces characters such as ₹ or Hindi letters with escape codes like \u20b9. Two arguments fix that: indent adds line breaks and spaces, and ensure_ascii=False keeps characters as they are.
import json
menu = {"shop": "Sharma Sweets", "kaju katli": "₹1,100/kg", "greeting": "नमस्ते"}
print(json.dumps(menu))
print(json.dumps(menu, indent=2, ensure_ascii=False)){"shop": "Sharma Sweets", "kaju katli": "\u20b91,100/kg", "greeting": "\u0928\u092e\u0938\u094d\u0924\u0947"}
{
"shop": "Sharma Sweets",
"kaju katli": "₹1,100/kg",
"greeting": "नमस्ते"
}Reading and writing JSON files
json.dump() and json.load(), without the s, work with files instead of strings. Open the file with encoding="utf-8" as you learned in Reading & Writing Files.
import json
from pathlib import Path
settings_file = Path("settings.json")
settings = {"theme": "dark", "language": "hi", "font_size": 16}
with settings_file.open("w", encoding="utf-8") as f:
json.dump(settings, f, indent=2, ensure_ascii=False)
with settings_file.open(encoding="utf-8") as f:
loaded = json.load(f)
loaded["font_size"] += 2
print(loaded)
try:
json.loads("{'theme': 'dark'}")
except json.JSONDecodeError as error:
print("Bad JSON:", error){'theme': 'dark', 'language': 'hi', 'font_size': 18}
Bad JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)The last part shows a classic error: single quotes are fine in Python but not in JSON, so loads() raises json.JSONDecodeError. Catch it whenever the JSON comes from a user, a file or the internet.
CSV: comma-separated values
A CSV file is a table stored as text. Each line is a row and commas separate the columns. Excel and Google Sheets open and save CSV files, so it is the easiest way to share tables with non-programmers.
You could split lines on commas yourself, but values that contain commas, such as "Kochi, Kerala", break that approach. The csv module handles quoting for you. Open CSV files with newline="", as the module documentation recommends, so line endings are not doubled on Windows.
import csv
rows = [
["name", "city", "fee"],
["Meera", "Kochi, Kerala", 1299],
["Rohan", "Lucknow", 999],
]
with open("students.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(rows)
with open("students.csv", encoding="utf-8") as f:
print(f.read())
with open("students.csv", newline="", encoding="utf-8") as f:
for row in csv.reader(f):
print(row)name,city,fee Meera,"Kochi, Kerala",1299 Rohan,Lucknow,999 ['name', 'city', 'fee'] ['Meera', 'Kochi, Kerala', '1299'] ['Rohan', 'Lucknow', '999']
The writer put quotes around Kochi, Kerala automatically, and the reader removed them. Notice that the fee comes back as the string '1299': CSV has no types, so every value you read is a string.
Rows as dictionaries
csv.DictWriter and csv.DictReader use the header row as keys, so you work with dictionaries instead of remembering column positions.
import csv
sales = [
{"item": "Notebook", "qty": 12, "price": 45},
{"item": "Gel pen", "qty": 30, "price": 10},
{"item": "Geometry box", "qty": 4, "price": 120},
]
with open("sales.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["item", "qty", "price"])
writer.writeheader()
writer.writerows(sales)
total = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
amount = int(row["qty"]) * int(row["price"])
total += amount
print(f"{row['item']:<13} ₹{amount}")
print(f"{'Total':<13} ₹{total}")Notebook ₹540 Gel pen ₹300 Geometry box ₹480 Total ₹1320
JSON or CSV?
Choose CSV for flat tables where every row has the same columns, especially if someone will open the data in a spreadsheet. Choose JSON for nested data (lists inside dictionaries), settings, and anything you send to or receive from a web API.
Common mistakes
- Mixing up
dumpanddumps. Thesversions work with strings; the others need a file object. - Writing JSON with single quotes by hand. JSON needs double quotes. Let
json.dumps()produce the text. - Forgetting that CSV values are strings. Convert with
int()orfloat()before doing maths. - Leaving out
newline=""for CSV files. On Windows you can get a blank line between every row.
Key points
json.dumps()andjson.loads()convert between Python data and JSON strings;json.dump()andjson.load()use files.- Use
indent=2for readable JSON andensure_ascii=Falseto keep ₹ and Indian scripts as they are. - Invalid JSON raises
json.JSONDecodeError; sets, dates and custom objects need converting first. - The
csvmodule handles quoting; open CSV files withnewline=""andencoding="utf-8". DictWriterandDictReaderlet you work with rows as dictionaries; all values come back as strings.
Exercise
A college canteen in Jaipur keeps its menu as a list of dictionaries with name, price and veg (True or False). Save the menu to menu.json with indentation, load it back, and then write only the vegetarian items to veg_menu.csv with a header row of name,price. Finally, print the contents of the CSV file.
Show solution
import csv
import json
from pathlib import Path
menu = [
{"name": "Masala dosa", "price": 60, "veg": True},
{"name": "Chicken roll", "price": 90, "veg": False},
{"name": "Veg thali", "price": 110, "veg": True},
]
Path("menu.json").write_text(json.dumps(menu, indent=2), encoding="utf-8")
loaded = json.loads(Path("menu.json").read_text(encoding="utf-8"))
with open("veg_menu.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "price"], extrasaction="ignore")
writer.writeheader()
writer.writerows(item for item in loaded if item["veg"])
print(Path("veg_menu.csv").read_text(encoding="utf-8"))name,price Masala dosa,60 Veg thali,110
extrasaction="ignore" tells DictWriter to skip the veg key, which is not one of the CSV columns. Without it, the writer raises ValueError for the unexpected key.
Quick Quiz
1. What does json.dumps({"ok": True, "note": None}) produce?
JSON uses double quotes, lowercase true and null.
2. Which function reads JSON from an open file?
load() reads from a file object; loads() parses a string.
3. You read a CSV row with DictReader and get row["fee"]. What type is it?
CSV files store only text, so every value comes back as a string.
4. Why use ensure_ascii=False with json.dumps()?
By default non-ASCII characters are escaped; ensure_ascii=False writes them as they are.
Learn Python with a mentor
Free lessons get you started. Our Python Programming training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
