5.2. JSON Read/Write

5.2.1. Mapping to JSON

  • json.dumps(DATA: dict) -> str

  • json.loads(DATA: str) -> dict

Serializing mapping to JSON:

import json


DATA = {'firstname': 'Mark',
        'lastname': 'Watney'}

result = json.dumps(DATA)

type(result)
# <class 'str'>
print(result)
# {"firstname": "Mark", "lastname": "Watney"}

Deserializing mapping from JSON:

import json


DATA = '{"firstname": "Mark", "lastname": "Watney"}'

result = json.loads(DATA)

type(result)
# <class 'dict'>
print(result)
# {'firstname': 'Mark', 'lastname': 'Watney'}

5.2.2. Sequence to JSON

  • json.dumps(data: Sequence[dict]) -> str

  • json.loads(data: str) -> list[dict]

Serializing sequence to JSON:

import json


DATA = [{'firstname': 'Melissa', 'lastname': 'Lewis'},
        {'firstname': 'Rick', 'lastname': 'Martinez'},
        {'firstname': 'Mark', 'lastname': 'Watney'}]

result = json.dumps(DATA)

type(result)
# <class 'str'>
print(result)
# [{"firstname": "Melissa", "lastname": "Lewis"},
#  {"firstname": "Rick", "lastname": "Martinez"},
#  {"firstname": "Mark", "lastname": "Watney"}]
import json


DATA = '[{"firstname": "Melissa", "lastname": "Lewis"}, {"firstname": "Rick", "lastname": "Martinez"}, {"firstname": "Mark", "lastname": "Watney"}]'

result = json.loads(DATA)

type(result)
# <class 'list'>
print(result)
# [{'firstname': 'Melissa', 'lastname': 'Lewis'},
#  {'firstname': 'Rick', 'lastname': 'Martinez'},
#  {'firstname': 'Mark', 'lastname': 'Watney'}]
import json

DATA = [('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')]

json.dumps(DATA)
# [["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"]]
import json
from pprint import pprint


DATA = '[["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"]]'

json.loads(DATA)
# [['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']]

5.2.3. Write JSON File

  • json.dump(data: dict, file: TextIOWrapper) -> None

  • file extension .json

Serialize to JSON:

import json

FILE = r'_temporary.json'

DATA = {'firstname': 'Mark',
        'lastname': 'Watney'}

with open(FILE, mode='w') as file:
    json.dump(DATA, file)


print(open(FILE).read())
# {"firstname": "Mark", "lastname": "Watney"}

5.2.4. Read JSON File

  • json.load(file: TextIOWrapper) -> dict

  • file extension .json

Serialize to JSON:

import json


FILE = r'_temporary.json'
DATA = '{"firstname": "Mark", "lastname": "Watney"}'
open(FILE, mode='w').write(DATA)


with open(FILE) as file:
    result = json.load(file)


type(result)
# <class 'dict'>
print(result)
# {'firstname': 'Mark', 'lastname': 'Watney'}

5.2.5. Assignments

Code 5.20. Solution
"""
* Assignment: JSON Read/Write Dump
* Complexity: easy
* Lines of code: 4 lines
* Time: 8 min

English:
    1. Extract from input a header and data
    2. Create `result: list[dict]`
        a. key - name from the header
        b. value - measurement or species
    3. Write structure to file `FILE` in JSON format
    4. Run doctests - all must succeed

Polish:
    1. Z danych wydziel nagłówek i pomiary
    2. Wygeneruj `result: list[dict]`
        a. klucz - nazwa z nagłówka
        b. wartość - wyniki pomiarów lub gatunek
    3. Zapisz strukturę do pliku `FILE` w formacie JSON
    4. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> type(result)
    <class 'list'>
    >>> len(result) > 0
    True
    >>> all(type(row) is dict
    ...     for row in result)
    True
    >>> from os import remove
    >>> result = open(FILE).read()
    >>> remove(FILE)
    >>> print(result)  # doctest: +NORMALIZE_WHITESPACE
    [{"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"}]
"""

FILE = '_temporary.json'

DATA = [('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')]


Code 5.21. Solution
"""
* Assignment: JSON Read/Write Load
* Complexity: easy
* Lines of code: 4 lines
* Time: 8 min

English:
    1. Read data from `FILE`
    2. Convert data to `result: list[tuple]`
    3. Do not 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. Nie dodawaj nagłówka jako pierwsza linia
    4. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> type(result)
    <class 'list'>
    >>> len(result) > 0
    True
    >>> all(type(row) is tuple
    ...     for row in result)
    True
    >>> result  # doctest: +NORMALIZE_WHITESPACE
    [(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')]
     >>> from os import remove
     >>> remove(FILE)
"""

FILE = r'_temporary.json'

DATA = """[{"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"}]"""

with open(FILE, mode='w') as file:
    file.write(DATA)

result: list = []