Python sort JSON based on value - python

I need to sort my JSON based on value in ascending/descending order in PYTHON
This is my JSON:
{
"efg": 1,
"mnp": 4,
"xyz": 3
}
expected output is :
{
"mnp": 4,
"xyz": 3,
"efg": 1,
}
The above is just a sample JSON, Actual JSON is much bigger
And how to reverse sort it based on value
{
"efg": 1,
"xyz": 3,
"mnp": 4
}
Please help
-Ashish

import json
from collections import OrderedDict
json_str = """
{
"efg": 1,
"mnp": 4,
"xyz": 3
}
"""
json_dict = json.loads(json_str)
dict_sorted = OrderedDict(sorted(json_dict.items(), key=lambda x: x[1]))
str_sorted = json.dumps(dict_sorted) # '{"efg": 1, "xyz": 3, "mnp": 4}'

Related

Parse all valid datetime strings in json recursively

I have a json blob of the following format. Is there a way to identify all strings which match the format
%Y-%m-%dT%H:%M:%S
And convert them to datettime strings
{
"data":[
{
"name":"Testing",
"dob":"2001-01-01T01:00:30"
},
{
"name":"Testing2",
"dob":"2001-01-01T01:00:30",
"licence_info":{
"issue_date":"2020-01-01T01:00:30"
}
}
]
}
The easiest way to do this is to parse each value and attempt to convert it to a datetime. You could do something like this:
from datetime import datetime
def convert_dates(value):
if isinstance(value, dict):
return { k : convert_dates(v) for k, v in value.items() }
elif isinstance(value, list):
return [ convert_dates(v) for v in value ]
else:
try:
dt = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')
return dt
except ValueError:
return value
jstr = '''
{
"data":[
{
"name":"Testing",
"dob":"2001-01-01T01:00:30"
},
{
"name":"Testing2",
"dob":"2001-01-01T01:00:30",
"licence_info":{
"issue_date":"2020-01-01T01:00:30"
}
}
]
}
'''
d = json.loads(jstr)
convert_dates(d)
Output:
{
'data': [
{'name': 'Testing',
'dob': datetime.datetime(2001, 1, 1, 1, 0, 30)
},
{'name': 'Testing2',
'dob': datetime.datetime(2001, 1, 1, 1, 0, 30),
'licence_info': {'issue_date': datetime.datetime(2020, 1, 1, 1, 0, 30)}
}
]
}

Unpack nodes of a dict for each slash in the key

I have a dict:
a = {
"group_a/category_a/metric_a": 5,
"group_a/category_a/metric_b": 4,
"group_a/category_b/metric_a": 3,
"group_a/category_b/metric_b": 2,
"group_b/category_a/metric_d": 1
}
I would like to unpack the nodes by creating a nested view, seperated by each slash, where the outcome looks as follows:
b = {
"group_a": {
"category_a": {
"metric_a": 5,
"metric_b": 4
},
"category_b": {
"metric_a": 3,
"metric_b": 2
},
"group_b": {
"category_a": {
"metric_d": 1
}
}
}
How can we go from a to b? I encountered this problem when trying to publish the dict above to Firebase as the nodes group_a/category_a/metric_a is not accepted, whereas a dict that is nested is allowed.
Loop through, split each key into a list of keys, create sub-dictionaries as required...
from pprint import pprint
a = {
"group_a/category_a/metric_a": 5,
"group_a/category_a/metric_b": 4,
"group_a/category_b/metric_a": 3,
"group_a/category_b/metric_b": 2,
"group_b/category_a/metric_d": 1
}
b = {}
for k, v in a.items():
dct = b
keys = k.split("/")
for key in keys[:-1]:
if key not in dct:
dct[key] = {}
dct = dct[key]
dct[keys[-1]] = v
pprint(b)
Gives:
{'group_a': {'category_a': {'metric_a': 5, 'metric_b': 4},
'category_b': {'metric_a': 3, 'metric_b': 2}},
'group_b': {'category_a': {'metric_d': 1}}}

Need Help in Python Dictionary Related Task

Consider a dictionary,
dictionary = {
'AE':{'Applied':4, 'Programming':3 },
'BE':{'Applied':4, 'Programming':2 },
'CE':{'Applied':4, 'Programming':5 },
}
With comprehension in definition, yield the output as,
output = [['AE':'BE':'CE'],
['Applied', 2,4,5],
['Programming', 5,3,2]]
You can use this code:
dictionary = {
'AE':{'Applied':4, 'Programming':3 },
'BE':{'Applied':4, 'Programming':2 },
'CE':{'Applied':4, 'Programming':5 },
}
output = []
dict_keys = list(dictionary.keys())
output.append(dict_keys)
for key in dictionary[dict_keys[0]]:
value = [dictionary[k][key] for k in dict_keys]
value.insert(0, key)
output.append(value)
Output:
output = [['AE', 'BE', 'CE'], ['Applied', 4, 4, 4], ['Programming', 3, 2, 5]]

Printing parsed JSON in Python

Assuming this is the .JSON file I have to parse:
{
"item": {
"allInventory": {
"onHand": 64,
"total": {
"1000": 0,
"1001": 6,
"1002": 5,
"1003": 3,
"1004": 12,
"1005": 0
}
}
},
"image": {
"tag": "/828402de-6cc8-493e-8abd-935a48a3d766_1.285a6f66ecf3ee434100921a3911ce6c.jpeg?odnHeight=450&odnWidth=450&odnBg=FFFFFF"
}
}
How would I go about printing the total values like:
1000 - 0
1001 - 6
1002 - 5
1003 - 4
1004 - 12
1005 - 0
I have already parsed the values, but I'm unsure of how to actually print them. I've already spent awhile on this and couldn't find a solution so any help is appreciated. Here is my code thus far:
import requests
import json
src = requests.get('https://hastebin.com/raw/nenowimite').json()
stats = src['item']['allInventory']['total']
print(stats)
This can be done through a for loop as follows:
for key in stats.keys():
print(key, '-', stats[key])
Using full Python 3.6 you can do (similarly than Ecir's answer)
for key, value in stats.items():
printf(f'{key} - {value}')
but being clearer about what is the key and the value and using the f-string interpolation.
You are almost there:
for item in stats.items():
print '%d - %d' % item
What this does is that stats is already a dict. Looking at the documentation, there is the items method which returns "a copy of the dictionary’s list of (key, value) pairs". And each pair is formatted as two numbers, i.e. '%d - %d'.
You can try:
>>> import json
>>> data= """{
"item": {
"allInventory": {
"onHand": 64,
"total": {
"1000": 0,
"1001": 6,
"1002": 5,
"1003": 3,
"1004": 12,
"1005": 0
}
}
},
"image": {
"tag": "/828402de-6cc8-493e-8abd-935a48a3d766_1.285a6f66ecf3ee434100921a3911ce6c.jpeg?odnHeight=450&odnWidth=450&odnBg=FFFFFF"
}
}"""
>>> data = json.loads(data)
>>> print data["item"]["allInventory"]["total"]
{'1005': 0, '1004': 12, '1003': 3, '1002': 5, '1001': 6, '1000': 0}

How to get a flat JSON from a nested one?

I have a nested JSON and I need "Max" & "Remaining" percentage values from it.
This is sample formula I am thinking of 100-(Remaining/Max)*100=(Value)
Sample JSON:
{
"ConcurrentAsyncGetReportInstances":
{
"Max": 5,
"Remaining": 3
},
"DailyApiRequests":
{
"Max":15000,"Remaining":14108
}
}
This is the JSON output.
I need to add the % value to the key
Sample output:
{
"ConcurrentAsyncGetReportInstances":40,(%value) 100-(5/3)*100
"DailyApiRequests": 5.95(%value) 100-(14108/15000)*100
}
Workarounds:
Tried to do make it a flat JSON and worked but didn't helped me
Worked on converting JSON into CSV and tried some but it was hard
Can someone suggest the best to do this? If possible provide some examples. Some help would also be appreciated.
Note: I am using Python 2.7
There is now a Python package for this called flatten_json. An introduction is provided here.
An example from that page--
In your shell:
> pip install flatten_json
In your Python console:
from flatten_json import flatten
input_dict = {
"a": 1,
"b": 2,
"c": [{"d": [2, 3, 4], "e": [{"f": 1, "g": 2}]}]
}
print(flatten(input_dict))
Results:
{'a': 1,
'b': 2,
'c_0_d_0': 2,
'c_0_d_1': 3,
'c_0_d_2': 4,
'c_0_e_0_f': 1,
'c_0_e_0_g': 2}
I've tested this in both Python 3.6 and 2.7.
Firstly receive your json and convert it to dictionary
import json
input_dict = json.loads(<your received son string>)
Then work on the input dict like below through recursive calls:
input_dict = {
"ConcurrentAsyncGetReportInstances":
{
"Max": 200,"Remaining":200
},
"DailyApiRequests":
{
"Max": 15000, "Remaining": 14108,
"Ant Migration Tool": {"Max": 0, "Remaining": 0},
"Chatter Desktop": {"Max": 0, "Remaining": 0},
"Chatter Mobile for BlackBerry":
{"Max": 0, "Remaining": 0},
"Chemical Equipment And Processing":
{"Max": 0,"Remaining": 0}
}
}
def flattenjson(input_dict, odict):
for ky in input_dict.keys():
if isinstance(input_dict[ky], dict):
if set(['Max', 'Remaining']).issubset(input_dict[ky].keys()):
if input_dict[ky]["Max"] != 0:
odict[ky] = 100-(float(input_dict[ky]["Remaining"])/input_dict[ky]["Max"])*100
else:
odict[ky] = 0
for iky in input_dict[ky].keys():
if isinstance(input_dict[ky][iky], dict):
tmp = {iky : input_dict[ky][iky]}
odict = flattenjson(tmp, odict)
return odict
odict = flattenjson(input_dict, dict())
print json.dumps(odict)
flattenjson helps you recursively work on to get your desired output for all Max and Remaining entries
You can retrieve nested values using the json library like so:
import json
sample_json = '{"ConcurrentAsyncGetReportInstances":{"Max": 5,"Remaining": 3},"DailyApiRequests": {"Max":15000,"Remaining":14108}}'
jason = json.loads(sample_json)
cagri_max = jason['ConcurrentAsyncGetReportInstances']['Max']
cagri_rem = jason['ConcurrentAsyncGetReportInstances']['Remaining']
You don't need to flatten the data structure. Just reference that pieces of it you want—so, for example, I think the following does essentially what you want:
import json
json_data = {
"ConcurrentAsyncGetReportInstances": {
"Max": 5,
"Remaining": 3
},
"DailyApiRequests": {
"Max": 15000,
"Remaining": 14108
}
}
def percentage_values(remaining, maximum):
return 100 - (float(remaining)/float(maximum)) * 100
# build output dictionary
json_out = {}
for key in json_data:
value = percentage_values(json_data[key]["Remaining"], json_data[key]["Max"])
json_out.update([(key, value)])
print(json.dumps(json_out, indent=4))
The resulting output showing the contents of json_out is:
{
"ConcurrentAsyncGetReportInstances": 40.0,
"DailyApiRequests": 5.9466666666666725
}
There are more succinct ways to write this in Python, but they all would do what is done above in a very simple manner.

Categories

Resources