
Python has an interesting way of handling structures within structures. Advanced users might know that arrays in Python are generic, and different data types can intermingle within the same array. In this article we will talk about JSON usage and node trees. For the JSON discussion, we will cover when it’s used and how to iterate through it. For our node tree discussion, we will cover how to create a node tree, why you might do so, and what benefits it has over arrays.
List of Dictionaries
To start, this article covers what Python sees as a list of dictionaries and lists; we know this as JSON. Though it should be made clear that JSON is actually a dictionary of other objects, Python lets you store them as arrays to create a deep level of data assignments. The main question is why to use JSON and when. JSON offers a standardized way of sending and receiving data to and from requests. JSON is a common form of reply when developing and interacting with API calls.
Getting and Storing JSON
As mentioned, JSON is typically a response to a request. One example of this is the response codes while interacting with Azure apis. For the purpose of this article, we will provide the JSON response as a variable, as the main focus is on how to interact with the data. Below is an example JSON response from a fictitious app.
{
"standings": [
{
"entries": [
{
"position": 1,
"previousPosition": 2,
"carNumber": "11",
"driverName": "Driver A",
"totalPoints": 761,
"rounds": [
{
"points": 187
},
{
"points": 190
},
{
"points": 190
},
{
"points": 194
},
{
"points": null
},
{
"points": null
}
]
},
{
"position": 2,
"previousPosition": 1,
"carNumber": "21",
"driverName": "Driver B",
"totalPoints": 753,
"rounds": [
{
"points": 193
},
{
"points": 170
},
{
"points": 197
},
{
"points": 193
},
{
"points": null
},
{
"points": null
}
]
}
]
}
]
}
To access the above JSON we need to call it a list by using the built-in JSON module from Python. Below is an example that loads the JSON and prints the object we want to the screen. Let’s say we want the total points of Driver B.
import json
import requests
def GetObj(json_response):
obj = json.loads(json_response)
return obj
def PrintPoints():
url = "http://localhost/raceresults"
r = requests.get(url = url, params = {})
obj = GetObj(r.json())
drivers = obj['standings']
print(str(drivers[0]['entries'][1]['totalPoints']))
return True
PrintPoints()
The immediate flaw with the code above is that it assumes that you know what position the driver is. If you only know the driver’s name, then we will need to get creative and compare driver values. Below is an example function that takes in a driver’s name and provides the total points.
import json
def GetObj(json_response):
obj = json.loads(json_response)
return obj
def PrintPoints(driverName):
obj = GetObj(r.json())
drivers = obj['standings']
for entries in drivers[0]['entries']:
if entries['driverName'] == driverName:
print(entries['totalPoints'])
return True
PrintPoints("Driver B")
Node Trees
While we could dedicate an entire post to node trees. We will briefly talk about what problem it solves and the advantages it has. We will conclude with an example of how to interact with a node tree in Python. Node trees are structures that look more like an organizational hierarchy than anything else. Node trees have ‘edges’ in the form of nodes. Each null node is the edge of the branch. The key problem node trees solve is sorting ability. Imagine using a list or dictionary of values. There are sorting algorithms you can use but frequent use of these on large data structures can cause performance degradation. A node tree allows the insertion of data in a presorted location. Non-binary trees can maintain relationships, such as an org chart. Using a dictionary poses the issue shown in the JSON example, where it needs to be iterated through with conditionals to get the right element. The biggest disadvantage of a node tree is the complexity required for implementation. Below is an example of a simple tree and how to insert data.
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
def insert(self, data):
if self.data:
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
def DisplayTree(self):
if self.left:
self.left.DisplayTree()
print( self.data),
if self.right:
self.right.DisplayTree()
rootNode = Node(50) #Create a root node and assign a number
rootNode.insert(25)
rootNode.insert(100)
rootNode.DisplayTree()