How to write a nested dictionary to json - python

I created a nested dictionary in Python like this:
{
"Laptop": {
"sony": 1
"apple": 2
"asus": 5
},
"Camera": {
"sony": 2
"sumsung": 1
"nikon" : 4
},
}
But I couldn't figure out how to write this nested dict into a json file. Any comments will be appreciated..!

d = {
"Laptop": {
"sony": 1,
"apple": 2,
"asus": 5,
},
"Camera": {
"sony": 2,
"sumsung": 1,
"nikon" : 4,
},
}
with open("my.json","w") as f:
json.dump(d,f)

Related

How do I 'append' a dictionary into an existing JSON dictionary using python?

Take a look at this example dictionary:
This is in a JSON file:
{
"fridge": {
"vegetables": {
"Cucumber": 0,
"Carrot": 2,
"Lettuce": 5
},
"drinks": {
"Water": 12,
"Juice": 4,
"Soda": 2
}
}
}
So in this example, we are showing the contents of my fridge, except we show the AMOUNT (2) of every ITEM (soda) in every CATEGORY (drinks). The way we did this, we firstly created a dictionary for the fridge and for every category we have another dictionary where inside it we have the item-type and amount of it.
Now let's say we went shopping... We bought some FRUITS at the supermarket and we got:
"fruits": {
"Apple": 3,
"Banana": 2,
"Melon": 1
}
We want to put this data (or fruits) into my fridge, except we don't have a CATEGORY for "fruits"!! So not only do we have to add a new dictionary into my fridge, but we also have data that we want to already add too!
Now this fridge thing was an example to help you understand what I want. So how do you insert a new dictionary into an already existing one with key-value pairs in it? In other words, I want my fridge to look like this:
{
"fridge": {
"vegetables": {
"Cucumber": 0,
"Carrot": 2,
"Lettuce": 5
},
"drinks": {
"Water": 12,
"Juice": 4,
"Soda": 2
},
"fruits": {
"Apple": 3,
"Banana": 2,
"Melon": 1
}
}
}
I tried APPEND but as expected, it does not work for dictionaries (it is for lists only) and so I do not know what to do... keep in mind that I do not want to re-define my data, I want to ADD data to existing data so that I can edit it later. Would appreciate some help, Thanks!
Suppose you have this string in proper json format:
j_str1='''\
{"fridge": {
"vegetables": {
"Cucumber": 0,
"Carrot": 2,
"Lettuce": 5
},
"drinks": {
"Water": 12,
"Juice": 4,
"Soda": 2
}
}}'''
And:
j_str2='''\
{"fruits": {
"Apple": 3,
"Banana": 2,
"Melon": 1
}}
'''
First convert to a Python dict:
import json
j=json.loads(j_str1)
>>> j
{'fridge': {'vegetables': {'Cucumber': 0, 'Carrot': 2, 'Lettuce': 5}, 'drinks': {'Water': 12, 'Juice': 4, 'Soda': 2}}}
Then update:
j["fridge"].update(json.loads(j_str2))
>>> j
{'fridge': {'vegetables': {'Cucumber': 0, 'Carrot': 2, 'Lettuce': 5}, 'drinks': {'Water': 12, 'Juice': 4, 'Soda': 2}, 'fruits': {'Apple': 3, 'Banana': 2, 'Melon': 1}}}
Then convert back into json:
>>> print(json.dumps(j,indent=3))
{
"fridge": {
"vegetables": {
"Cucumber": 0,
"Carrot": 2,
"Lettuce": 5
},
"drinks": {
"Water": 12,
"Juice": 4,
"Soda": 2
},
"fruits": {
"Apple": 3,
"Banana": 2,
"Melon": 1
}
}
}

pandas.to_json suppress indentation for lists as values

I have a DataFrame with lists in one column.
I want to pretty print the data as JSON.
How can I use indentation without affecting the values in each cell to be indented.
An example:
df = pd.DataFrame(range(3))
df["lists"] = [list(range(i+1)) for i in range(3)]
print(df)
output:
0 lists
0 0 [0]
1 1 [0, 1]
2 2 [0, 1, 2]
Now I want to print the data as JSON using:
print(df.to_json(orient="index", indent=2))
output:
{
"0":{
"0":0,
"lists":[
0
]
},
"1":{
"0":1,
"lists":[
0,
1
]
},
"2":{
"0":2,
"lists":[
0,
1,
2
]
}
}
desired output:
{
"0":{
"0":0,
"lists":[0]
},
"1":{
"0":1,
"lists":[0,1]
},
"2":{
"0":2,
"lists":[0,1,2]
}
}
If you don't want to bother with json format output, you can just turn the list type to string temporarily when printing the dataframe
print(df.astype({'lists':'str'}).to_json(orient="index", indent=2))
{
"0":{
"0":0,
"lists":"[0]"
},
"1":{
"0":1,
"lists":"[0, 1]"
},
"2":{
"0":2,
"lists":"[0, 1, 2]"
}
}
If you don't want to see the quote mark, you use regex to replace them
import re
import re
result = re.sub(r'("lists":)"([^"]*)"', r"\1 \2",
df.astype({'lists':'str'}).to_json(orient="index", indent=2))
{
"0":{
"0":0,
"lists": [0]
},
"1":{
"0":1,
"lists": [0, 1]
},
"2":{
"0":2,
"lists": [0, 1, 2]
}
}

How to create a cross join of a list and a dictionary?

I would like to create a cross join of a list and a dictionary. With the joint part being the list string and dictionary key. Please see the example:
status = ["old", "new"]
scores = {
"boat A" : {
"min": 5,
"max": 6
},
"boat B" : {
"min": 5,
"max": 6
}
}
The result crossing join:
cross_join = {
"boat A old" : {
"min": 5,
"max": 6
},
"boat B old" : {
"min": 5,
"max": 6
},
"boat A new" : {
"min": 5,
"max": 6
},
"boat B new" : {
"min": 5,
"max": 6
}
}
Edit: my approach is to loop through the dictionary and append to the key. It works, but its not a beautiful or fast approach given these lists and dictionary's are huge.
You can use dictionary comprehension
res = {f'{k} {x}': v for x in status for k, v in scores.items()}
print(res)

How to get specific data from JSON object in Python

I have a dict stored under the variable parsed:
{
"8119300029": {
"store": 4,
"total": 4,
"web": 4
},
"8119300030": {
"store": 2,
"total": 2,
"web": 2
},
"8119300031": {
"store": 0,
"total": 0,
"web": 0
},
"8119300032": {
"store": 1,
"total": 1,
"web": 1
},
"8119300033": {
"store": 0,
"total": 0,
"web": 0
},
"8119300034": {
"store": 2,
"total": 2,
"web": 2
},
"8119300036": {
"store": 0,
"total": 0,
"web": 0
},
"8119300037": {
"store": 0,
"total": 0,
"web": 0
},
"8119300038": {
"store": 2,
"total": 2,
"web": 2
},
"8119300039": {
"store": 3,
"total": 3,
"web": 3
},
"8119300040": {
"store": 3,
"total": 3,
"web": 3
},
"8119300041": {
"store": 0,
"total": 0,
"web": 0
}
}
I am trying to get the "web" value from each JSON entry but can only get the key values.
for x in parsed:
print(x["web"])
I tried doing this ^ but kept getting this error: "string indices must be integers". Can somebody explain why this is wrong?
because your x variable is dict key name
for x in parsed:
print(parsed[x]['web'])
A little information on your parsed data there: this is basically a dictionary of dictionaries. I won't go into too much of the nitty gritty but it would do well to read up a bit on json: https://www.w3schools.com/python/python_json.asp
In your example, for x in parsed is iterating through the keys of the parsed dictionary, e.g. 8119300029, 8119300030, etc. So x is a key (in this case, a string), not a dictionary. The reason you're getting an error about not indexing with an integer is because you're trying to index a string -- for example x[0] would give you the first character 8 of the key 8119300029.
If you need to get each web value, then you need to access that key in the parsed[x] dictionary:
for x in parsed:
print(parsed[x]["web"])
Output:
4
2
0
...

Combine two JSON by addition python 2.7

I want to combine two JSON which have the same form and increment the differents array which already exists in one JSON :
JSON a :
[
{
"productTitle": "Product1",
"api-activity": {
"api1": 1
},
"totalCalls": 1
},
{
"productTitle": "Product2",
"api-activity": {
"api1": 1,
"api2": 2,
"api3": 3,
"api4": 4
},
"totalCalls": 10
}
]
JSON b:
[
{
"productTitle": "Product1",
"api-activity": {
"api1": 1
},
"totalCalls": 1
},
{
"productTitle": "Product2",
"api-activity": {
"api1": 1,
"api2": 2,
"api3": 3,
"api4": 4
},
"totalCalls": 10
},
{
"productTitle": "Product3",
"api-activity": {
"api1": 2
},
"totalCalls": 2
}
]
To obtain something like this :
[
{
"productTitle": "Product1",
"api-activity": {
"api1": 2
},
"totalCalls": 2
},
{
"productTitle": "Product2",
"api-activity": {
"api1": 2,
"api2": 4,
"api3": 6,
"api4": 8
},
"totalCalls": 20
},
{
"productTitle": "Product3",
"api-activity": {
"api1": 2
},
"totalCalls": 2
}
]
I try to combine them using a previous script I used where I compare the existing JSON to a dataList(which here is our second JSON) like this :
import json
with open('testa.json') as json_data:
json_a = json.load(json_data)
with open('testb.json') as json_data:
json_b = json.load(json_data)
with open('outputMerge.json', 'w') as f:
data_list = json_a
for data in json_b:
title = data["productTitle"] #get all product title
exist = False
for existing_data in data_list: #loop in data_list
if data["api-activity"] in existing_data["api-activity"]:
print ("true")
but I have an error with the differents keys I use :
Traceback (most recent call last):
File "merge.py", line 17, in
if data["api-activity"] in existing_data["api-activity"]:
TypeError: unhashable type: 'dict'
Can you help me debugging I think I'm close or if you have a better solution maybe ?
I would approach this by loading your counts into a Counter() object, using the tuple (title, api) as the key. This can then be converted back into an output dictionary, for example:
Counter({('Product2', 'api4'): 8, ('Product2', 'api3'): 6, ('Product2', 'api2'): 4, ('Product1', 'api1'): 2, ('Product2', 'api1'): 2, ('Product3', 'api1'): 2})
This can be done as follows:
from collections import Counter
from itertools import groupby
import json
api_counts = Counter()
def update_counters(json_filename):
with open(json_filename) as f_json:
for product in json.load(f_json):
title = product['productTitle']
api_counts.update({(title, api) : count for api, count in product['api-activity'].items()})
update_counters('testa.json')
update_counters('testb.json')
output = []
for product, apis in groupby(sorted(api_counts.items()), lambda x: x[0][0]):
api_activity = {}
total_calls = 0
for (p, api), count in apis:
api_activity[api] = count
total_calls += count
output.append({'productTitle': product, 'api-activity' : api_activity, 'totalCalls' : total_calls})
with open('outputMerge.json', 'w') as f_output:
json.dump(output, f_output, indent=4)
Giving you the following output:
[
{
"productTitle": "Product1",
"api-activity": {
"api1": 2
},
"totalCalls": 2
},
{
"productTitle": "Product2",
"api-activity": {
"api1": 2,
"api2": 4,
"api3": 6,
"api4": 8
},
"totalCalls": 20
},
{
"productTitle": "Product3",
"api-activity": {
"api1": 2
},
"totalCalls": 2
}
]

Categories

Resources