Learn
🤖 AI Hub 📰 News 📖 Dictionary 🧰 Resources
Grow
💼 Jobs 🚀 Community 🏆 Challenges
Explore by Stage
🌑 Zero 📚 Learn 🔧 Practice 🏗 Build 🚀 Launch 💰 Earn
Account
Login Sign Up
🏗️HTML 🎨CSS ⚡JavaScript 🐙Git & GitHub ⚛️React Soon 📘TypeScript Soon 🐍Python 🗄️Database & SQL Soon 🌐Web Development Soon ☁️Cloud & DevOps Soon 🤖AI & ML Soon 📄Resume Prep Soon 🎤Interview Prep Soon 💼Freelancing Soon 🚀SaaS & Side Projects Soon 🤖Automation Soon
Intermediate 🕑 10 min read 👁 2 views 📅 Oct 22, 2026

JSON and CSV: Saving and Sharing Data

Save and share data with Python's json and csv modules. Read a marks spreadsheet, calculate averages and convert it into JSON for an app, with Hindi names kept readable.

From a Spreadsheet to an App

Bright Future Coaching Centre has 300 students. The office keeps every student’s test marks in a spreadsheet. Every Sunday, after the weekly test, the results must also appear in the institute’s mobile app, where parents check them. The spreadsheet and the app speak different “languages”, and someone has to translate between them.

The spreadsheet can be saved as a CSV file: plain text with one row per line and commas between the values. The app expects JSON: plain text that looks almost exactly like Python dictionaries and lists. These two formats are everywhere. Banks export statements as CSV, websites send data as JSON, and almost every programming language can read both.

In this lesson you will use Python’s built-in json and csv modules to save data, read it back, work with nested data, calculate averages from a marks sheet and convert CSV into JSON, just like the coaching centre needs.

Each run starts in an empty folder. In the playground, every example first creates the files it needs and then reads them. On your own computer the files stay in your project folder, so you can open them in VS Code or a spreadsheet program.

What Is JSON?

JSON stands for JavaScript Object Notation, but it is not only for JavaScript. It is a simple text format for structured data. If you know Python dictionaries and lists, you can already read it. There are a few small differences:

JSONPython
{"name": "Asha"} (object)dict
[1, 2, 3] (array)list
"text" (always double quotes)str
42, 3.5int, float
true / falseTrue / False
nullNone

Python to JSON Text: json.dumps

json.dumps() (“dump string”) turns Python data into JSON text. Two options make the output much nicer:

  • indent=2 puts each item on its own line, indented by 2 spaces, so humans can read it.
  • ensure_ascii=False keeps letters like Hindi, Tamil or the ₹ symbol as they are. Without it, Python writes them as codes like \u092a, which are correct but impossible to read.
import json

student = {
    "roll_no": 101,
    "name": "प्रिया शर्मा",
    "course": "JEE Foundation",
    "fees_paid": True,
    "scholarship": None,
}

print(json.dumps(student))
print()
print(json.dumps(student, indent=2, ensure_ascii=False))

Compare the two outputs. The first is one long line with the Hindi name turned into codes. The second is clear and readable. Also notice that True became true and None became null.

JSON Text to Python: json.loads

json.loads() (“load string”) does the reverse. It reads JSON text and gives you normal Python dictionaries and lists that you can loop over and index.

import json

# Text that arrived from the institute's app
reply = '{"roll_no": 102, "name": "Arjun Rao", "present": true, "rank": null, "marks": [78, 85, 91]}'

data = json.loads(reply)

print(type(data))            # <class 'dict'>
print(data["name"])          # Arjun Rao
print(data["present"])       # True
print(data["rank"])          # None
print(sum(data["marks"]))    # 254

An easy way to remember: the s at the end of dumps and loads means string.

Saving and Reading JSON Files

For files, use the versions without the “s”: json.dump(data, file) writes to an open file and json.load(file) reads from one. Open the file with with open(...) as you learned in the Files lesson, and add encoding="utf-8" so that every language is saved correctly.

import json

results = {
    "batch": "NEET Morning",
    "toppers": ["Meera", "Kabir", "Sana"],
    "average": 82.4,
}

# 1. Save to a file (this creates results.json)
with open("results.json", "w", encoding="utf-8") as f:
    json.dump(results, f, indent=2, ensure_ascii=False)

# 2. Read it back, as another program would
with open("results.json", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded["toppers"][0])     # Meera
print(loaded == results)        # True

The last line prints True: what came out of the file is exactly what went in. This is how apps remember settings, scores and records between runs.

Nested Data

Real JSON is often nested: dictionaries inside lists inside dictionaries. To reach a value, follow the path one step at a time, from the outside in. For example, batch["teacher"]["name"] means “in batch, take teacher, then take name”.

import json

batch_json = """
{
  "batch": "JEE Evening",
  "teacher": {"name": "Mr. Iyer", "subject": "Physics"},
  "students": [
    {"name": "Riya", "marks": {"physics": 88, "maths": 92}},
    {"name": "Dev", "marks": {"physics": 67, "maths": 74}}
  ]
}
"""

batch = json.loads(batch_json)

print("Teacher:", batch["teacher"]["name"])
for student in batch["students"]:
    physics = student["marks"]["physics"]
    print(f"{student['name']} scored {physics} in Physics")
Lost inside nested data? Print one level at a time, for example print(batch.keys()) and then print(batch["students"][0]). You will soon see the shape.

CSV Files with csv.writer and csv.reader

A CSV (comma-separated values) file is a table in plain text. The first row is usually the header with column names. You could split lines on commas yourself, but values can contain commas too, like Kavya, R.. The csv module handles this for you by putting such values in quotes.

import csv

rows = [
    ["roll_no", "name", "maths", "science"],
    [101, "Asha", 78, 85],
    [102, "Imran", 91, 88],
]

# newline="" stops extra blank lines on Windows
with open("marks.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerows(rows)                 # many rows at once
    writer.writerow([103, "Kavya, R.", 69, 74])   # one more row

with open("marks.csv", encoding="utf-8") as f:
    print(f.read())

with open("marks.csv", newline="", encoding="utf-8") as f:
    for row in csv.reader(f):
        print(row)

Look at the printed file: the name with a comma is wrapped in quotes, and csv.reader reads it back correctly as one value. Each row comes back as a list of strings, even the numbers.

Always open CSV files with newline="". Without it, files written on Windows can have an empty line after every row.

DictWriter and DictReader

Working with positions like row[2] is easy to get wrong. csv.DictWriter and csv.DictReader let you use column names instead. DictReader uses the header row as keys, so each row becomes a dictionary.

import csv

students = [
    {"name": "Asha", "city": "Pune", "maths": 78},
    {"name": "Imran", "city": "Lucknow", "maths": 91},
]

with open("students.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "city", "maths"])
    writer.writeheader()
    writer.writerows(students)

with open("students.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        print(row["name"], "from", row["city"], "scored", row["maths"])
        print(type(row["maths"]))   # <class 'str'>

Notice <class 'str'>: CSV has no number type, so everything you read is text. Convert with int() or float() before you do maths.

Real-Life Example: Weekly Test Results for the App

Here is the full Sunday job for Bright Future Coaching Centre. The program creates the marks sheet (in real life, the office exports it), reads it, calculates each student’s average, marks who passed (40 or more), saves the results as JSON for the app and prints a summary.

import csv
import json

# Step 1: create the spreadsheet file (normally the office exports it)
sheet = """name,physics,chemistry,maths
Asha Verma,78,82,91
Rohan Das,65,58,72
Fatima Khan,92,88,95
Vikram Singh,35,30,38
"""
with open("test_marks.csv", "w", newline="", encoding="utf-8") as f:
    f.write(sheet)

# Step 2: read it and work out each student's average
results = []
with open("test_marks.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        marks = [int(row["physics"]), int(row["chemistry"]), int(row["maths"])]
        average = round(sum(marks) / len(marks), 1)
        results.append({
            "name": row["name"],
            "average": average,
            "passed": average >= 40,
        })

# Step 3: save the results as JSON for the app
with open("results.json", "w", encoding="utf-8") as f:
    json.dump({"test": "Weekly Test 7", "results": results}, f, indent=2)

# Step 4: print a summary
for r in results:
    status = "Pass" if r["passed"] else "Needs support"
    print(f"{r['name']:<14} {r['average']:>5}  {status}")

class_average = round(sum(r["average"] for r in results) / len(results), 1)
print("Class average:", class_average)

with open("results.json", encoding="utf-8") as f:
    saved = json.load(f)
print("Saved", len(saved["results"]), "results to results.json")

Four steps, about 40 lines, and a job that took someone an hour every week now takes less than a second. This “read CSV, calculate, write JSON” pattern appears in thousands of real offices.

Try these changes:

  1. Add a fifth student to the sheet text and run again.
  2. Add a "grade" key: “A” for an average of 85 or more, “B” for 60 or more, otherwise “C”.
  3. Also save the results as a new CSV file with DictWriter.

Common Mistakes

  • Single quotes in JSON. JSON strings must use double quotes. Python-style single quotes fail:
import json

data = json.loads("{'name': 'Asha'}")   # ERROR: JSONDecodeError

Fix: use double quotes inside the JSON text (and single quotes around the Python string):

import json

data = json.loads('{"name": "Asha"}')
print(data["name"])   # Asha
  • Doing maths with CSV text. sum([row["maths"] for row in rows]) raises a TypeError, because the values are strings. Fix: convert each one with int() or float().
  • Mixing up dump and dumps. json.dumps(data, f) does not write to the file. Fix: use json.dump(data, f) for files and json.dumps(data) for strings.
  • Expecting every Python type to survive. JSON keys are always strings, so {1: "Asha"} comes back as {"1": "Asha"}. Tuples come back as lists, and dates cannot be saved at all until you turn them into text first.
  • Forgetting newline="" or encoding="utf-8". You get blank rows on Windows or broken Hindi names. Add both every time you open a CSV file.

Practice Task: Fee Register to JSON

The coaching centre’s fee register is a CSV file with one row per payment. Write a program that adds up how much each student has paid and saves the totals as JSON.

  • Read fees.csv with csv.DictReader (the starter code creates the file).
  • Add up the amounts for each student in the totals dictionary. Remember to convert to int.
  • Save totals to fees_summary.json with indent=2.
  • Read the JSON file back and print each name with the total, like Asha: Rs 3000.
import csv
import json

# The fee register (this code creates the file for you)
register = """name,month,amount
Asha,July,1500
Imran,July,1500
Asha,August,1500
Kavya,July,1000
Imran,August,1500
"""
with open("fees.csv", "w", newline="", encoding="utf-8") as f:
    f.write(register)

totals = {}

# TODO 1: open fees.csv and read it with csv.DictReader
# TODO 2: add each amount (as an int) to totals[name]
# TODO 3: save totals to fees_summary.json with indent=2
# TODO 4: read fees_summary.json back and print each name and total
Show one possible answer (try it yourself first!)
import csv
import json

register = """name,month,amount
Asha,July,1500
Imran,July,1500
Asha,August,1500
Kavya,July,1000
Imran,August,1500
"""
with open("fees.csv", "w", newline="", encoding="utf-8") as f:
    f.write(register)

totals = {}

with open("fees.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        name = row["name"]
        totals[name] = totals.get(name, 0) + int(row["amount"])

with open("fees_summary.json", "w", encoding="utf-8") as f:
    json.dump(totals, f, indent=2)

with open("fees_summary.json", encoding="utf-8") as f:
    summary = json.load(f)

for name, total in summary.items():
    print(f"{name}: Rs {total}")

# Asha: Rs 3000
# Imran: Rs 3000
# Kavya: Rs 1000

Key Takeaways

  • JSON is text that looks like Python dicts and lists; CSV is a table as text, with commas between values.
  • json.dumps and json.loads work with strings; json.dump and json.load work with files.
  • Use indent=2 for readable JSON and ensure_ascii=False to keep Hindi and other scripts as they are.
  • Use csv.DictReader and csv.DictWriter to work with column names instead of positions.
  • Everything read from a CSV file is a string: convert numbers before doing maths.
  • Open files with encoding="utf-8", and CSV files also with newline="".

❓ Frequently Asked Questions

CSV stores a simple table: rows and columns of text. JSON can store nested data such as lists inside dictionaries, and it keeps types like numbers, true, false and null.
json.dumps returns the JSON as a string. json.dump writes it straight into an open file. The same rule applies to json.loads and json.load.
By default json escapes every non-English character. Pass ensure_ascii=False to json.dump or json.dumps, and open the file with encoding="utf-8".
Yes. Spreadsheet programs open CSV files directly, and you can also save any spreadsheet as CSV so Python can read it.
No. The built-in csv module is enough for most tasks. pandas is a separate library that helps with very large tables and analysis, and you can learn it later.
Was this lesson helpful?

🎯 Finished this lesson?

🔗 Related Tutorials
🤖 Got a Doubt? Ask AI
Get instant answers in Hindi or English
🤖
Z2T Bot
Online
Ask me anything about this tutorial — I'm here! 👋