18.7. JSON Recap
JavaScript Object Notation
The most popular format for data exchange
JSON format is similar to
dict
notation in PythonFields are always enclosed only by double quote
"
characterInstead of
True
there istrue
(lowercase)Instead of
False
there isfalse
(lowercase)Instead of
None
there isnull
list
is known asarray
(despite the same syntax)JSON has no
tuple
orset
Coma
,
is not allowed after the last element in list or objectObject of type
tuple
will serialize aslist
Object of type
set
is not JSON serializabledict
is known asobject
(despite the same syntax)Coma
,
is not allowed after the last element in list or objectcamelCase
is convention, althoughsnake_case
is also validFields are always enclosed only by double quote
"
characterUnicode characters are stored as unicode entities (
"cze\\u015b\\u0107"
)JSON can be minified to save space for network transmission
Minified JSON is not human readable
Use
python -m json.tool
to prettify (humanize) output
18.7.1. Assignments
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: JSON File Load
# - Difficulty: easy
# - Lines: 2
# - Minutes: 5
# %% English
# 1. Read data from `FILE`
# 2. Convert data to `result: list[tuple]`
# 3. Add header as a first line
# 4. Run doctests - all must succeed
# %% Polish
# 1. Odczytaj dane z pliku `FILE`
# 2. Przekonwertuj dane do `result: list[tuple]`
# 3. Dodaj nagłówek jako pierwszą linię
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - `with open(mode='rt') as file:`
# - `json.load()`
# - `dict.keys()`
# - `dict.values()`
# - `tuple()`
# - `list.append()`
# - `list.extend()`
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from os import remove
>>> remove(FILE)
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert len(result) > 0, \
'Variable `result` should not be empty'
>>> assert all(type(row) is tuple for row in result), \
'Variable `result` should be a list[tuple]'
>>> from pprint import pprint
>>> pprint(result)
[('sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species'),
(5.8, 2.7, 5.1, 1.9, 'virginica'),
(5.1, 3.5, 1.4, 0.2, 'setosa'),
(5.7, 2.8, 4.1, 1.3, 'versicolor'),
(6.3, 2.9, 5.6, 1.8, 'virginica'),
(6.4, 3.2, 4.5, 1.5, 'versicolor'),
(4.7, 3.2, 1.3, 0.2, 'setosa'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa')]
"""
import json
FILE = r'_temporary.json'
with open(FILE, mode='wt') as file:
file.write("""[
{"sepal_length": 5.8, "sepal_width": 2.7, "petal_length": 5.1, "petal_width": 1.9, "species": "virginica"},
{"sepal_length": 5.1, "sepal_width": 3.5, "petal_length": 1.4, "petal_width": 0.2, "species": "setosa"},
{"sepal_length": 5.7, "sepal_width": 2.8, "petal_length": 4.1, "petal_width": 1.3, "species": "versicolor"},
{"sepal_length": 6.3, "sepal_width": 2.9, "petal_length": 5.6, "petal_width": 1.8, "species": "virginica"},
{"sepal_length": 6.4, "sepal_width": 3.2, "petal_length": 4.5, "petal_width": 1.5, "species": "versicolor"},
{"sepal_length": 4.7, "sepal_width": 3.2, "petal_length": 1.3, "petal_width": 0.2, "species": "setosa"},
{"sepal_length": 7.0, "sepal_width": 3.2, "petal_length": 4.7, "petal_width": 1.4, "species": "versicolor"},
{"sepal_length": 7.6, "sepal_width": 3.0, "petal_length": 6.6, "petal_width": 2.1, "species": "virginica"},
{"sepal_length": 4.9, "sepal_width": 3.0, "petal_length": 1.4, "petal_width": 0.2, "species": "setosa"}
]""")
# type: list[tuple]
result = ...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: JSON File Blanks
# - Difficulty: medium
# - Lines: 13
# - Minutes: 13
# %% English
# 1. Read data from `FILE`
# 2. Convert data to `result: list[tuple]`
# 3. Add sorted header as a first line
# 4. Replace empty values with `None`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Odczytaj dane z pliku `FILE`
# 2. Przekonwertuj dane do `result: list[tuple]`
# 3. Dodaj posortowany nagłówek jako pierwszą linia
# 4. Zamień wartości puste na `None`
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - `with open(mode='rt') as file:`
# - `json.load()`
# - `dict.keys()`
# - `dict.values()`
# - `dict.get(default=None)`
# - `dict comprehension`
# - `tuple()`
# - `set()`
# - `set.update()`
# - `set.add()`
# - `sorted()`
# - `list.append()`
# - `list.extend()`
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from os import remove
>>> remove(FILE)
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert len(result) > 0, \
'Variable `result` should not be empty'
>>> assert all(type(row) is tuple for row in result), \
'Variable `result` should be a list[tuple]'
>>> from pprint import pprint
>>> pprint(result)
[('petal_length', 'petal_width', 'sepal_length', 'sepal_width', 'species'),
(None, None, None, None, 'virginica'),
(1.4, 0.2, None, 3.5, 'setosa'),
(4.1, 1.3, 5.7, None, 'versicolor'),
(None, 1.8, 6.3, 2.9, 'virginica'),
(4.5, None, 6.4, 3.2, 'versicolor'),
(None, None, 4.7, 3.2, 'setosa'),
(4.7, 1.4, None, None, 'versicolor'),
(None, 2.1, 7.6, None, 'virginica'),
(1.4, None, None, 3.0, 'setosa')]
"""
import json
FILE = r'_temporary.json'
with open(FILE, mode='wt') as file:
file.write("""[
{"species": "virginica"},
{"sepal_width": 3.5, "petal_length": 1.4, "petal_width": 0.2, "species": "setosa"},
{"sepal_length": 5.7, "petal_length": 4.1, "petal_width": 1.3, "species": "versicolor"},
{"sepal_length": 6.3, "sepal_width": 2.9, "petal_width": 1.8, "species": "virginica"},
{"sepal_length": 6.4, "sepal_width": 3.2, "petal_length": 4.5, "species": "versicolor"},
{"sepal_length": 4.7, "sepal_width": 3.2, "species": "setosa"},
{"petal_length": 4.7, "petal_width": 1.4, "species": "versicolor"},
{"sepal_length": 7.6, "petal_width": 2.1, "species": "virginica"},
{"sepal_width": 3.0, "petal_length": 1.4, "species": "setosa"}
]""")
# type: list[tuple]
result = ...