Q1What does json.dumps({"name": "café"}, ensure_ascii=False) include in its output?
json and csv — I/O for Structured Data
This article is part of the Python Course, where you master from scratch all the skills you need to use Python, from the fundamentals through to advanced topics.
Learn json.dumps / loads two-way conversion and ensure_ascii, csv.writer / reader positional access, and DictWriter / DictReader column-name access on Titanic data.
This article covers I/O for two common structured data formats — json, frequently used by web APIs, and csv, which opens cleanly in spreadsheet software.
json — Two-Way Conversion Between Python Objects and JSON Strings
JSON (JavaScript Object Notation) is a lightweight text format that expresses structure with just "key/value pairs" and "ordered lists", used as the standard for web API responses and config files. Python's json module converts dicts, lists, strings, numbers, bools, and None to and from JSON.
Two basic functions are enough to remember. json.dumps(object) converts Python → JSON string, and json.loads(string) converts JSON string → Python. The trailing s stands for string — it sets them apart from dump / load, which work directly with files.
s (dump / load) work directly with file objects.| Function | Role | Notes |
|---|---|---|
| json.dumps(obj) | Python → JSON string | returns a str |
| json.loads(text) | JSON string → Python | returns a dict / list / etc. |
| json.dump(obj, file) | Python → write to file | pass the f from open() |
| json.load(file) | file → Python | pass the f from open() |
| indent=N | pretty-print with N-space indent | for human readers |
| ensure_ascii=False | emit non-ASCII as-is | the default escapes them |
ensure_ascii defaults to True
By default, json.dumps({"name": "café"}) outputs '{"name": "caf\u00e9"}' — non-ASCII characters get escaped as \u. It's technically valid, but hard for humans to read and bloats file size, so for data containing non-ASCII characters (accents, emoji, CJK, etc.), make a habit of passing ensure_ascii=False.
csv Basics — Handle Rows with reader and writer
CSV (Comma-Separated Values) is a plain format where one comma-separated line equals one record, and since spreadsheet software like Excel can open it directly, it's everywhere in business workflows. Python's csv module provides functions for reading and writing this format row by row.
The basics are csv.writer(file) and csv.reader(file): the former writes a list of values as a single row, the latter reads CSV one row at a time as a list of values. Two gotchas: first, everything you read back is a string — if you need integers, convert with int() yourself. Second, always pass newline='' to open(...) so the csv module can manage newline characters itself.
Always pass newline='' to open
The csv module manages newline characters itself, so you need to pass newline='' like open("x.csv", "w", newline=''). Skip it and you can end up with CSVs that contain blank rows on Windows — a classic gotcha called out in the official Python docs.
DictWriter and DictReader — Read and Write by Column Name
The csv.writer / reader from the previous section work by position, so adding columns or changing their order forces you to rewrite every row[0] / row[1] access. DictWriter / DictReader are versions that read and write by column name (header) — you can write a list of dicts straight to CSV and read it back as a list of dicts.
Real-world data is mostly CSVs with a header row, so in actual projects you'll reach for these far more often.
fieldnames. DictReader does the reverse — reads a CSV with a header row as a list of dicts, so you can access values by column name like row["name"].Real-world Example: Aggregate titanic.csv
So far we've made small datasets in code and written them out. Let's finish by reading a real dataset and aggregating it. The subject is the famous Titanic dataset on Kaggle (891 rows / 12 columns), with columns like PassengerId / Survived (0 = died, 1 = survived) / Pclass (cabin class) / Name / Sex / Age / Fare.
The python_console for the practice preloads the external CSV into the in-browser virtual filesystem (VFS) via fileUrls, so your code can just call open("titanic.csv"). We'll write the same task with both csv.reader (positional) and csv.DictReader (by column name).
Knowledge Check
Answer each question one by one.
Q2What's the type of values returned when reading rows back with csv.reader?
Q3What's best suited for reading a CSV with a header row as a list of dicts?