I have a JSON file with a complex structure. This file stores categories of some sort. Each category and sub-category has its 'ID' like
2 drinks
2.1 drinks coffee
2.1.1 drinks coffee instant
2.1.2 drinks coffee real
2.2 drinks tea
2.3 drinks water
For example, suppose I want to add a new category, 'alcohol'. The proper place for it us as a subcategory of 'drinks'. So I type 2 press Enter, type alcohol press Enter, and the program creates a new dictionary with a key 'drinks' like this: nd={"drinks":{"alcohol":""}} Then it updates the existing large dictionary with that new one.
As I am new in Python and in coding at all, I've done it in a very ugly way by making that new dictionary using exec because I lack skills. Also the code doesn't work properly, for example if I want to add not to existing dictionary like drinks but to just a value of key like adding 'soda' to 'water' it will have an error. I might make a workaround for it but in the same messy way. So I just ask for help and explanation how to do it in pythonic way.
To be concise: I have a set of keys that form the 'path' for new value like:
communication | mobile | verizon | calls | out | roaming | Other country
Using this 'path' I must upgrade a dict with new value, if last step in 'path' is that value - convert it to dict and then add new value.
here goes sample of JSON file:
{
"food": {
"dairy": {
"cheese": "Gauda",
"milk": {
"origin": "place",
"brand": "name"
}
}
},
"communication": {
"mobile": {
"life": {
"txt": "",
"calls": ""
},
"vodafone": {
"txt": "",
"subscr": "",
"mms": "",
"calls": {
"in": {
"home": "",
"roaming": ""
},
"out": {
"home": "",
"roaming": ""
}
},
"internet": ""
},
"verizon": {
"txt": "",
"subscr": "",
"mms": "",
"calls": {
"in": {
"home": "",
"roaming": ""
},
"out": {
"home": "500 min",
"roaming": "Other country",
"reached": ""
}
},
"internet": "1Gb"
}
},
"internet": "SomeProviderName"
},
"taxes": "",
"drinks": {
"water": "",
"tea": "",
"coffee": {
"real": "",
"instant": ""
}}}
Here's the code by itself:
#!/usr/bin/env python -tt
# -*- coding: utf-8 -*-
import json
import collections
def walk_dict(d, key=None, parent=None):
res = {}
for i, e in enumerate(sorted(d), 1):
k = (key + "." + str(i)) if key else str(i)
p = (parent + " | " + e ) if parent else e
if isinstance(d[e], dict):
res[k] = p
res.update(walk_dict(d[e], k, p))
else:
res[k] = p + " | " + str(d[e])
return res
with open('new_cat.json') as f:
cat_data = json.load(f)
new_data = walk_dict(cat_data)
for v in sorted(new_data):
print v, new_data[v]
def find_cat(d,new_cat):
ex_str="{"
for i in d:
print i
ex_str+="\""+i+"\":{"
ex_str+="\""+new_cat+"\":\"\""+"}"*(len(d)+1)
print ex_str
return ex_str
inp=raw_input("pick one (numbers) or \'ENTER\' for new in root\n")
if inp=='':
new_cat=raw_input("input new category\n")
upd=find_cat([],new_cat)
else:
print new_data[inp]
new_cat=raw_input("input new category\n")
keys=new_data[inp].split(" | ")
upd=find_cat(keys,new_cat)
exec "nd="+str(upd)
def update(d, u):
for k, v in u.iteritems():
if isinstance(v, collections.Mapping):
r = update(d.get(k, {}), v)
d[k] = r
else:
d[k] = u[k]
return d
update(cat_data,nd)
for i in cat_data:
print i, cat_data[i]
f=open("new_cat.json",'w')
json.dump(cat_data,f,indent=4,encoding='utf-8',ensure_ascii=False,sort_keys=False,separators=(',', ': '))
f.close()
Aucun commentaire:
Enregistrer un commentaire