Handling JSON in Python

  • Elements of JSON format
  • Python supports JSON natively. It comes with built-in packages for encoding and decoding JSON data
  • The process of encoding JSON is called serialization - for storing or transmitting across a network
  • Deserialization is the process of decoding data
  • JSON looks like a python dictionary
  • JSON provides two methods - .dump() & .dumps(). If we want to use the serialzed object within the netbook then we should use dumps, which will be a str object
  • JSON provides two methods - .load() and .loads(). loads is used to handle python objects without reading it from the file. For example, if we are making a http request, then we can handle the response by using the .loads() methos

Import Package and create data

import json
data = {
  "name": "John",
  "age": 25,
  "city": "New York",
  "interests": [
    "reading",
    "hiking",
    "cooking"
  ],
  "is_student": True,
  "grades": {
    "math": 90,
    "english": 85,
    "history": 95
  }
}

Write JSON file to disk

with open("data_file.json", "w") as write_file:
    json.dump(data, write_file)

Reading JSON file

with open("data_file.json", "r") as data_file:
    data = json.load(data_file)
data
{'name': 'John',
 'age': 25,
 'city': 'New York',
 'interests': ['reading', 'hiking', 'cooking'],
 'is_student': True,
 'grades': {'math': 90, 'english': 85, 'history': 95}}
type(data)
dict

Handling API requests which returns a JSON object

import json
import requests
response = requests.get("https://jsonplaceholder.typicode.com/todos")
type(response)
requests.models.Response
type(response.text)
str
# We are using loads here instead of load which handles str object
todos = json.loads(response.text)
type(todos)
list
todos[0]
{'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}

Manipulating JSON

# Determine which users have completed the most tasks
todos_for_user = {}

for todo in todos:
    if todo["completed"]:
        try:
            todos_for_user[todo['userId']] += 1
        except KeyError:
            todos_for_user[todo['userId']] = 1
todos_for_user
{1: 11, 2: 8, 3: 7, 4: 6, 5: 12, 6: 6, 7: 9, 8: 11, 9: 8, 10: 12}
# create a sorted list of userId, complete pairs
top_users = sorted(todos_for_user.items(),
                    key=lambda x: x[1], reverse=True)
top_users
[(5, 12),
 (10, 12),
 (1, 11),
 (8, 11),
 (7, 9),
 (2, 8),
 (9, 8),
 (3, 7),
 (4, 6),
 (6, 6)]

Create a JSON with completed Todos for each user

users = []
max_complete = 11
for user, num_complete in top_users:
    if num_complete < max_complete:
        break
    users.append(str(user))
str(5) in users
True
def keep(todo):
    is_complete = todo["completed"]
    has_max_count = str(todo["userId"]) in users
    return is_complete and has_max_count
output = list(filter(keep,todos))