python-course.eu

15. JSON and PYTHON

By Bernd Klein. Last modified: 01 Feb 2022.

Introduction

JSON stands for JavaScript Object Notation. JSON is an open standard file and data interchange format. The content of a JSON file or JSON data is human-readable. JSON is used for storing and exchanging data. The JSON data objects consist of attribute–value pairs. The data format of JSON looke very similar to a Python dictionary, but JSON is a language-independent data format. The JSON syntax is derived from JavaScript object notation syntax, but the JSON format is text only. JSON filenames use the extension .json.

JSON

Live Python training

instructor-led training course

Enjoying this page? We offer live Python training courses covering the content of this site.

See our Python training courses

See our Machine Learning with Python training courses

dumps and load

It is possible to serialize a Python dict object to a JSON formatted string by using dumps from the json module:

import json

d = {"a": 3, "b": 3, "c": 12}

json.dumps(d)

OUTPUT:

'{"a": 3, "b": 3, "c": 12}'

The JSON formatted string looks exactly like a Python dict in a string format. In the followoing example, we can see a difference: "True" and "False" are turned in "true" and "false":

d = {"a": True, "b": False, "c": True}

d_json = json.dumps(d)
d_json

OUTPUT:

'{"a": true, "b": false, "c": true}'

We can transform the json string back in a Python dictionary:

json.loads(d_json)

OUTPUT:

{'a': True, 'b': False, 'c': True}

Differences between JSON and Python Dictionaries

If you got the idea that turning dictionaries in json strings is always structure-preserving, you are wrong:

persons = {"Isabella": {"surname": "Jones",
                       "address": ("Bright Av.", 
                                   34, 
                                   "Village of Sun")},
           "Noah": {"surname": "Horton",
                    "address": (None, 
                                None, 
                                "Whoville")}
          }


persons_json = json.dumps(persons)                                
print(persons_json)                          

OUTPUT:

{"Isabella": {"surname": "Jones", "address": ["Bright Av.", 34, "Village of Sun"]}, "Noah": {"surname": "Horton", "address": [null, null, "Whoville"]}}

We can see that the address tuple is turned into a list!

json.loads(persons_json)

OUTPUT:

{'Isabella': {'surname': 'Jones',
  'address': ['Bright Av.', 34, 'Village of Sun']},
 'Noah': {'surname': 'Horton', 'address': [None, None, 'Whoville']}}

You can prettyprint JSON by using the optinional indent parameter:

persons_json = json.dumps(persons, indent=4)                                
print(persons_json) 

OUTPUT:

{
    "Isabella": {
        "surname": "Jones",
        "address": [
            "Bright Av.",
            34,
            "Village of Sun"
        ]
    },
    "Noah": {
        "surname": "Horton",
        "address": [
            null,
            null,
            "Whoville"
        ]
    }
}

Live Python training

instructor-led training course

Enjoying this page? We offer live Python training courses covering the content of this site.

Upcoming online Courses

See our Python training courses

See our Machine Learning with Python training courses

Relationship between Python dicts and JSON Objects

PYTHON OBJECT JSON OBJECT
dict object
list, tuple array
str string
int, long, float numbers
True true
False false
None null
import json

d = {"d": 45, "t": 123}
x = json.dumps(d)
print(x)

lst = [34, 345, 234]
x = json.dumps(lst)
print(x)

int_obj = 199
x = json.dumps(int_obj)
print(x)

OUTPUT:

{"d": 45, "t": 123}
[34, 345, 234]
199

There is another crucial difference, because JSON accepts onls keys str, int, float, bool or None as keys, as we can see in the following example:

board = {(1, "a"): ("white", "rook"),
         (1, "b"): ("white", "knight"),
         (1, "c"): ("white", "bishop"),
         (1, "d"): ("white", "queen"),
         (1, "e"): ("white", "king"),
         # further data skipped
        }

Calling json.dumps with board as an argument would result in the exeption TypeError: keys must be str, int, float, bool or None, not tuple.

To avoid this, we could use the optional key skipkeys:

board_json = json.dumps(board, 
                       skipkeys=True)

board_json

OUTPUT:

'{}'

We avoided the exception, but the result is not satisfying, because the data is missing!

A better solution is to turn the tuples into string, as we do in the following:

board2 = dict((str(k), val) for k, val in board.items())
board2

OUTPUT:

{"(1, 'a')": ('white', 'rook'),
 "(1, 'b')": ('white', 'knight'),
 "(1, 'c')": ('white', 'bishop'),
 "(1, 'd')": ('white', 'queen'),
 "(1, 'e')": ('white', 'king')}
board_json = json.dumps(board2)
board_json

OUTPUT:

'{"(1, \'a\')": ["white", "rook"], "(1, \'b\')": ["white", "knight"], "(1, \'c\')": ["white", "bishop"], "(1, \'d\')": ["white", "queen"], "(1, \'e\')": ["white", "king"]}'
 

board2 = dict((str(k[0])+k[1], val) for k, val in board.items())
board2

OUTPUT:

{'1a': ('white', 'rook'),
 '1b': ('white', 'knight'),
 '1c': ('white', 'bishop'),
 '1d': ('white', 'queen'),
 '1e': ('white', 'king')}

board_json = json.dumps(board2) board_json

board2 = dict((str(key[0])+key[1],