serializing json in python - python

I know there are quite a few json/python questions out there but I can't seem to figure this one out. I am trying to serialize two lists into the same file. In order to do that I create a new class that holds the two lists:
class newJSON(object):
def __init__(self, list1, list2):
self.data = {'data': list1, 'info' : list2}
I need the resulting data file to look like the following:
{
"data" : [
{
"name" : "aName" ,
"coordinates" : {"obj2" : 33, "obj3" : 71}
} , {
"name" : "bName" ,
"coordinates" : {"obj2" : 12, "obj3" : 77}
}
] ,
"info" : [
{
"first" : ["xxx" , "yyy"] ,
"space" : 21
} , {
"first" : ["aaa" , "bbb"] ,
"space" : 12
}
]
}
So then I go to decode the object as recommended in Serializing python object instance to JSON and several others:
jsonToEncode = newJSON(myList1, myList2)
myNewJSONData = json.dumps(jsonToEncode.__dict__)
However I get the "is not JSON serializable error"... I have tried this with and without the dict but to no success. The JSON must be in the format shown above. What is the problem?
Thanks
****EDIT****
in order to make the two lists, I take a json file which is formatted exactly like the json shown and do the following:
list1 = [obj1(**myObj) for myObj in data["data"]]
and the same for list2. obj1 is made like this:
class obj1(object):
def__init__(self, name, coordinates):
self.name = name
self.coordinate = coordinates

There is no need to create a new object. Simply serialize the dictionary directly:
myNewJSONData = json.dumps({'data': list1, 'info': list2})
However, your code should have worked otherwise. You probably have data contained in list1 and list2 that is not serializable.

Try myNewJSONData = json.dumps(jsonToEncode.data) instead.
Or even myNewJSONData = json.dumps({'data': list1, 'info' : list2}). Why do you use that class jsonToEncode anyway?

try this:
myNewJSONData = json.dumps(jsonToEncode.data, indent=2)
or this:
>>> class newJSON2(dict):
... def __init__(self, list1, list2):
... self['data'] = list1
... self['info'] = list2
>>>
>>>
>>> json2 = newJSON2(list1, list2)
>>> json2
{'info': [{'space': 21, 'first': ['xxx', 'yyy']}, {'space': 12, 'first': ['aaa', 'bbb']}], 'data': [{'name': 'aName', 'coordinates': {'obj3': 71, 'obj2': 33}}, {'name': 'bName', 'coordinates': {'obj3': 77, 'obj2': 12}}]}
>>> print json.dumps(json2, indent=2)
{
"info": [
{
"space": 21,
"first": [
"xxx",
"yyy"
]
},
{
"space": 12,
"first": [
"aaa",
"bbb"
]
}
],
"data": [
{
"name": "aName",
"coordinates": {
"obj3": 71,
"obj2": 33
}
},
{
"name": "bName",
"coordinates": {
"obj3": 77,
"obj2": 12
}
}
]
}
>>>

Use simplejson library.
from simplejson import loads, dumps
print loads(json_string) # Converts a JSON string to dict
print dumps(python_object) # Converts any valid python object/dict to valid JSON string
Take a look at https://pypi.python.org/pypi/simplejson.

Related

need to turn JSON values into keys

I have some json that I would like to transform from this:
[
{
"name":"field1",
"intValue":"1"
},
{
"name":"field2",
"intValue":"2"
},
...
{
"name":"fieldN",
"intValue":"N"
}
]
into this:
{ "field1" : "1",
"field2" : "2",
...
"fieldN" : "N",
}
For each pair, I need to change the value of the name field to a key, and the values of the intValue field to a value. This doesn't seem like flattening or denormalizing. Are there any tools that might do this out-of-the-box, or will this have to be brute-forced? What's the most pythonic way to accomplish this?
parameters = [ # assuming this is loaded already
{
"name":"field1",
"intValue":"1"
},
{
"name":"field2",
"intValue":"2"
},
{
"name":"fieldN",
"intValue":"N"
}
]
field_int_map = dict()
for p in parameters:
field_int_map[p['name']] = p['intValue']
yields {'field1': '1', 'field2': '2', 'fieldN': 'N'}
or as a dict comprehension
field_int_map = {p['name']:p['intValue'] for p in parameters}
This works to combine the name attribute with the intValue as key:value pairs, but the result is a dictionary instead of the original input type which was a list.
Use dictionary comprehension:
json_dct = {"parameters":
[
{
"name":"field1",
"intValue":"1"
},
{
"name":"field2",
"intValue":"2"
},
{
"name":"fieldN",
"intValue":"N"
}
]}
dct = {d["name"]: d["intValue"] for d in json_dct["parameters"]}
print(dct)
# {'field1': '1', 'field2': '2', 'fieldN': 'N'}

How do I parse nested json objects?

I am trying to load a JSON file to parse the contents nested in the root object. Currently I have the JSON file open and loaded as such:
with open(outputFile.name) as f:
data = json.load(f)
For the sake of the question here is an example of what the contents of the JSON file are like:
{
"rootObject" :
{
"person" :
{
"address" : "some place ave. 123",
"age" : 47,
"name" : "Joe"
},
"kids" :
[
{
"age" : 20,
"name" : "Joey",
"studySubject":"math"
},
{
"age" : 16,
"name" : "Josephine",
"studySubject":"chemistry"
}
],
"parents" :
{
"father" : "Joseph",
"mother" : "Joette"
}
How do I access the nested objects in "rootObject", such as "person", "kids" and its contents, and "parents"?
Below code using recursive function can extract values using specific key in a nested dictionary or 'lists of dictionaries':
data = {
"rootObject" :
{
"person" :
{
"address" : "some place ave. 123",
"age" : 47,
"name" : "Joe"
},
"kids" :
[
{
"age" : 20,
"name" : "Joey",
"studySubject":"math"
},
{
"age" : 16,
"name" : "Josephine",
"studySubject":"chemistry"
}
],
"parents" :
{
"father" : "Joseph",
"mother" : "Joette"
}
}}
def get_vals(nested, key):
result = []
if isinstance(nested, list) and nested != []: #non-empty list
for lis in nested:
result.extend(get_vals(lis, key))
elif isinstance(nested, dict) and nested != {}: #non-empty dict
for val in nested.values():
if isinstance(val, (list, dict)): #(list or dict) in dict
result.extend(get_vals(val, key))
if key in nested.keys(): #key found in dict
result.append(nested[key])
return result
get_vals(data, 'person')
Output
[{'address': 'some place ave. 123', 'age': 47, 'name': 'Joe'}]
The code for loading the JSON object should look like this:
from json import loads, load
with open("file.json") as file:
var = loads(load(file))
# loads() transforms the string in a python dict object

get data from a json

I want to get the data from a json. I have the idea of a loop to access all levels.
I have only been able to pull data from a single block.
print(output['body']['data'][0]['list'][0]['outUcastPkts'])
How do I get the other data?
import json,urllib.request
data = urllib.request.urlopen("http://172.0.0.0/statistic").read()
output = json.loads(data)
for elt in output['body']['data']:
print(output['body']['data'][0]['inUcastPktsAll'])
for elt in output['list']:
print(output['body']['data'][0]['list'][0]['outUcastPkts'])
{
"body": {
"data": [
{
"inUcastPktsAll": 3100617019,
"inMcastPktsAll": 7567,
"inBcastPktsAll": 8872,
"outPktsAll": 8585575441,
"outUcastPktsAll": 8220240108,
"outMcastPktsAll": 286184143,
"outBcastPktsAll": 79151190,
"list": [
{
"outUcastPkts": 117427359,
"outMcastPkts": 1990586,
"outBcastPkts": 246120
},
{
"outUcastPkts": 0,
"outMcastPkts": 0,
"outBcastPkts": 0
}
]
},
{
"inUcastPktsAll": 8269483865,
"inMcastPktsAll": 2405765,
"inBcastPktsAll": 124466,
"outPktsAll": 3101194852,
"outUcastPktsAll": 3101012296,
"outMcastPktsAll": 173409,
"outBcastPktsAll": 9147,
"list": [
{
"outUcastPkts": 3101012296,
"outMcastPkts": 90488,
"outBcastPkts": 9147
},
{
"outUcastPkts": 0,
"outMcastPkts": 0,
"outBcastPkts": 0
}
]
}
],
"msgs": [ "successful" ]
},
"header": {
"opCode": "1",
"token": "",
"state": "",
"version": 1
}
}
output = json.loads(data) #Type of output is a dictionary.
#Try to use ".get()" method.
print(output.get('body')) #Get values of key 'body'
print(output.get('body').get('data')) #Get a list of key 'data'
If a key doesn't exist, the '.get()' method will return None.
https://docs.python.org/3/library/stdtypes.html#dict.get
In python you can easily iterate over the objects of a list like so:
>>> l = [1, 2, 3, 7]
>>> for elem in l:
... print(elem)
...
1
2
3
7
This works regarding what can of object do you have in the list (integers, tuples, dictionaries). Having that in mind, your solution was not far off, you only to do the following changes:
for entry in output['body']['data']:
print(entry['inUcastPktsAll'])
for list_element in entry['list']:
print(list_element['outUcastPkts'])
This will give you the following for the json object you have provided:
3100617019
117427359
0
8269483865
3101012296
0

i want to convert sample JSON data into nested JSON using specific key-value in python

I have below sample data in JSON format :
project_cost_details is my database result set after querying.
{
"1": {
"amount": 0,
"breakdown": [
{
"amount": 169857,
"id": 4,
"name": "SampleData",
"parent_id": "1"
}
],
"id": 1,
"name": "ABC PR"
}
}
Here is full json : https://jsoneditoronline.org/?id=2ce7ab19af6f420397b07b939674f49c
Expected output :https://jsoneditoronline.org/?id=56a47e6f8e424fe8ac58c5e0732168d7
I have this sample JSON which i created using loops in code. But i am stuck at how to convert this to expected JSON format. I am getting sequential changes, need to convert to tree like or nested JSON format.
Trying in Python :
project_cost = {}
for cost in project_cost_details:
if cost.get('Parent_Cost_Type_ID'):
project_id = str(cost.get('Project_ID'))
parent_cost_type_id = str(cost.get('Parent_Cost_Type_ID'))
if project_id not in project_cost:
project_cost[project_id] = {}
if "breakdown" not in project_cost[project_id]:
project_cost[project_id]["breakdown"] = []
if 'amount' not in project_cost[project_id]:
project_cost[project_id]['amount'] = 0
project_cost[project_id]['name'] = cost.get('Title')
project_cost[project_id]['id'] = cost.get('Project_ID')
if parent_cost_type_id == cost.get('Cost_Type_ID'):
project_cost[project_id]['amount'] += int(cost.get('Amount'))
#if parent_cost_type_id is None:
project_cost[project_id]["breakdown"].append(
{
'amount': int(cost.get('Amount')),
'name': cost.get('Name'),
'parent_id': parent_cost_type_id,
'id' : cost.get('Cost_Type_ID')
}
)
from this i am getting sample JSON. It will be good if get in this code only desired format.
Also tried this solution mention here : https://adiyatmubarak.wordpress.com/2015/10/05/group-list-of-dictionary-data-by-particular-key-in-python/
I got approach to convert sample JSON to expected JSON :
data = [
{ "name" : "ABC", "parent":"DEF", },
{ "name" : "DEF", "parent":"null" },
{ "name" : "new_name", "parent":"ABC" },
{ "name" : "new_name2", "parent":"ABC" },
{ "name" : "Foo", "parent":"DEF"},
{ "name" : "Bar", "parent":"null"},
{ "name" : "Chandani", "parent":"new_name", "relation": "rel", "depth": 3 },
{ "name" : "Chandani333", "parent":"new_name", "relation": "rel", "depth": 3 }
]
result = {x.get("name"):x for x in data}
#print(result)
tree = [];
for a in data:
#print(a)
if a.get("parent") in result:
parent = result[a.get("parent")]
else:
parent = ""
if parent:
if "children" not in parent:
parent["children"] = []
parent["children"].append(a)
else:
tree.append(a)
Reference help : http://jsfiddle.net/9FqKS/ this is a JavaScript solution i converted to Python
It seems that you want to get a list of values from a dictionary.
result = [value for key, value in project_cost_details.items()]

How to update a key in a list of dictionaries in Python

I have a very simple use case in which I have to update a key inside a list of dictionaries. The code goes like this:
original = [
{
"name": "Subhayan",
"age": 34
},
{
"name": "Poulomi",
"age": 30
}
]
update_data = {
"Subhayan": 50,
"Poulomi": 46
}
check = [x["age"] = update_data[x["name"]] for x in original]
print(check)
I have this strange error :
File "try_defaultdict.py", line 17
check = [x["age"] = update_data[x["name"]] for x in original]
^
SyntaxError: invalid syntax
I know this can be done using a simple for loop. But I am wondering if I can use the list comprehension method for doing this?
Maybe you want to create new dictionaries? In that case, this is possible and okay:
check = [{"name": x["name"], "age": update_data[x["name"]]} for x in original]
Result:
>>> check
[{'name': 'Subhayan', 'age': 50}, {'name': 'Poulomi', 'age': 46}]
Try this, this way, you can update the value in place:
original = [
{
"name": "Subhayan",
"age" : 34
},
{
"name": "Poulomi",
"age" : 30
}
]
update_data = {
"Subhayan" : 50,
"Poulomi" : 46
}
[x.update({"age": update_data.get(x["name"])}) for x in original]
print(original)

Categories