How to Make Nested JSON Object with Python - python

I need to make JSON output that looks like the following
{ "items": [
"number": {
"value": 23
"label": test
}
]
}
I've done something similar with the code below but I can't figure out how I need to nest number under items.
#!/usr/bin/python
import json
myjson = {'items':[]}
d = {}
d['value'] = 23
d['label'] = "test"
myjson.get('items').append(d)
output = json.dumps(myjson)
print output
That gives me
{
"items": [{
"value": 23,
"label": "test"}
]}

Your input JSON isn't proper, it should be something like:
{ "items":
[
{
"number":
{
"value": 23,
"label": "test"
}
}
]
}
Besides that it can get messy, but accessing the resultant dict is intuitive.
jdict = json.loads(yourjson)
jdict['items'] => [{"number":{...}}]
jdict['items'][0] => {"number":{...}}
jdict['items'][0]['number']['value'] => 23
Edit:
Think you actually just wanted this:
myjson.get('items').append({'number': d})
You have to append a dictionary, not entries of a dictionary to items.

Related

remove Keys and values in python json

I have some data which looks like this :
{
"key_value": [
{
"key": "name",
"value": "kapil"
},
{
"key": "age",
"value": "36"
}
]
}
I need to convert it to look like this:
{
"age": "36",
"name": "kapil"
}
Would somebody be able to help with this?
I have already tried using json.dumps()
I'm not sure why you were trying to use json.dumps, but all you need to do is loop through all the pairs and add them to a new dictionary. Like this:
data = {
"key_value": [
{
"key": "name",
"value": "kapil"
},
{
"key": "age",
"value": "36"
}
]
}
res = {}
for pair in data["key_value"]:
res[pair["key"]] = pair["value"]
print(res)
Note that if your data is in JSON, then you need to use json.loads() to convert your JSON to a dictionary, then use json.dumps() to convert that dictionary back to a string that can be written to a file.

convert list array to json

I'm working on taking a JSON feed and filtering out only the items I want from my list. I'm appending the items I'd like to keep to each list identifier. However, when I convert to JSON the output is incorrect. You can see the ACTUAL OUTPUT example below. The target output below is what I'm actually expecting. I've tried orienting the list with index and records, but no luck.
#TARGET OUTPUT
{
"id":"1",
"Name":"xxx",
"Image":"https://xxx.xxx.png",
},
{
"id":"2",
"Name":"xx2",
"Image":"https://xx2.xxx.png",
}
#ACTUAL OUTPUT
{
"id": ["1","2",]
},
{
"image":["https://xxx.xxx.png","https://xx2.xxx.png"]
},
{
"name":["xxx", "xx2"]
},
#CODE
# JSON feed
{
"document": {
"id": "1",
"image": "https://xxx.xxx.png",
"name": "xxx",
},
},
{
"document": {
"id": "2",
"image": "https://xx2.xxx.png",
"name": "xx2",
},
},
# create list array
list = {'id':[], 'Name': [], 'Image': []}
links = {'id': [], 'Image': []}
# loop through and append items
def getData(hits):
for item in filter(None, hits):
item = item['document']
list['id'].append(item['id'])
links['id'].append(item['id'])
links['Image'].append(item['image'])
list['Image'].append(item['image'])
list['Name'].append(item['name'])
# get first page
pageNum = 1
data = getDataPerPage(pageNum)
try:
itemsNo = data['found']
getData(data['hits'])
while itemsNo > 24:
itemsNo -= 24
pageNum += 1
data = getDataPerPage(pageNum)
getData(data['hits'])
except:
print("broken")
# save list to json
with open('./output/data_chart.json', 'w') as f:
f.write(json.dumps(list))
When you receive multiple JSON objects, those are in the form of a list (so between []). You could:
covert JSON string to python dictionary using json.loads()
filter using the dict
dump dictionary into a JSON string using json.dumps()
input = """[
{"document":
{"id": "1","image": "https://xxx.xxx.png","name": "xxx"}},
{"document":
{"id": "2","image": "https://xx2.xxx.png","name": "xx2"}}
]"""
input_dic = json.loads(input)
tmp = []
for item in input_dic:
tmp.append(json.dumps(item["document"]))
output = json.dumps(tmp)
print(output)
Hope I got your question.
It's not 100% clear what you have or what you want, but with a few assumptions (input is list of dict, desired output is list of dict):
json_obj = [
{
"document": {
"id": "1",
"image": "https://xxx.xxx.png",
"name": "xxx",
},
},
{
"document": {
"id": "2",
"image": "https://xx2.xxx.png",
"name": "xx2",
},
},
]
desired_output = [x["document"] for x in json_obj]
print(desired_output)

Populating JSON data from API in Python pandas DataFrame - TypeError and IndexError

I am trying to populate a pandas DataFrame with select information from JSON output fetched from an API.
candidate_list = []
for candidate in candidate_response['data']:
if 'error' not in candidate_response:
candidate_list.append([candidate['id'], candidate['attributes']['first_name'], candidate['attributes']
['last_name'], candidate['relationships']['educations']['data']['id']])
The DataFrame populates fine until I add candidate['relationships']['educations']['data']['id'], which throws TypeError: list indices must be integers or slices, not str.
When trying to get the values of the indexes for ['id'] by using candidate['relationships']['educations']['data'][0]['id'] instead, I get IndexError: list index out of range.
The JSON output looks something like:
"data": [
{
"attributes": {
"first_name": "Tester",
"last_name": "Testman",
"other stuff": "stuff",
},
"id": "732887",
"relationships": {
"educations": {
"data": [
{
"id": "605372",
"type": "educations"
},
{
"id": "605371",
"type": "educations"
},
{
"id": "605370",
"type": "educations"
}
]
}
},
How would I go about successfully filling a column in the DataFrame with the 'id's under 'relationships'>'educations'>'data'?
Please note then when using candidate['relationships']['educations']['data']['id'] you get that error because at data there is a list, and not a dictionary. And you cannot access dictionary by name.
Assuming, what you are trying to achieve is one entry per data.attributes.relationships.educations.data entry. Complete code that works and does what you are trying is:
import json
json_string = """{
"data": [
{
"attributes": {
"first_name": "Tester",
"last_name": "Testman",
"other stuff": "stuff"
},
"id": "732887",
"relationships": {
"educations": {
"data": [
{
"id": "605372",
"type": "educations"
},
{
"id": "605371",
"type": "educations"
},
{
"id": "605370",
"type": "educations"
}
]
}
}
}
]
}"""
candidate_response = json.loads(json_string)
candidate_list = []
for candidate in candidate_response['data']:
if 'error' not in candidate_response:
for data in candidate['relationships']['educations']['data']:
candidate_list.append(
[
candidate['id'],
candidate['attributes']['first_name'],
candidate['attributes']['last_name'],
data['id']
]
)
print(candidate_list)
Code run available at ideone.
I have analyzed your code and also ran it on Jupyter notebook all looks good, I am getting the output,
The error you got list indices must be integers or slices, not str, that is because you were not using the index, this required because the value which you are looking for that is in the list.
and about this error: IndexError: list index out of range. Maybe some code typo mistake is done from your side otherwise the code is fine.
here is the output of your following code:
candidate_list = []
for candidate in candidate_response['data']:
if 'error' not in candidate_response:
candidate_list.append([candidate['id'], candidate['attributes']['first_name'], candidate['attributes']['last_name'],candidate['relationships']['educations']['data'][0]['id']])
Output
probably for any candidate candidate['relationships']['educations']['data'] is an empty list

Extracting data from JSON depending on other parameters

What are the options for extracting value from JSON depending on other parameters (using python)? For example, JSON:
"list": [
{
"name": "value",
"id": "123456789"
},
{
"name": "needed-value",
"id": "987654321"
}
]
When using json_name["list"][0]["id"] it obviously returns 123456789. Is there a way to indicate "name" value "needed-value" so i could get 987654321 in return?
For example:
import json as j
s = '''
{
"list": [
{
"name": "value",
"id": "123456789"
},
{
"name": "needed-value",
"id": "987654321"
}
]
}
'''
js = j.loads(s)
print [x["id"] for x in js["list"] if x["name"] == "needed-value"]
The best way to handle this is to refactor the json as a single dictionary. Since "name" and "id" are redundant you can make the dictionary with the value from "name" as the key and the value from "id" as the value.
import json
j = '''{
"list":[
{
"name": "value",
"id": "123456789"
},{
"name": "needed-value",
"id": "987654321"
}
]
}'''
jlist = json.loads(j)['list']
d = {jd['name']: jd['id'] for jd in jlist}
print(d) ##{'value': '123456789', 'needed-value': '987654321'}
Now you can iterate the items like you normally would from a dictionary.
for k, v in d.items():
print(k, v)
# value 123456789
# needed-value 987654321
And since the names are now hashed, you can check membership more efficiently than continually querying the list.
assert 'needed-value' in d
jsn = {
"list": [
{
"name": "value",
"id": "123456789"
},
{
"name": "needed-value",
"id": "987654321"
}
]
}
def get_id(list, name):
for el in list:
if el['name'] == name:
yield el['id']
print(list(get_id(jsn['list'], 'needed-value')))
Python innately treats JSON as a list of dictionaries. With this in mind, you can call the index of the list you need to be returned since you know it's location in the list (and child dictionary).
In your case, I would use list[1]["id"]
If, however, you don't know where the position of your needed value is within the list, the you can run an old fashioned for loop this way:
for user in list:
if user["name"] == "needed_value":
return user["id"]
This is assuming you only have one unique needed_value in your list.

Output an existing defaultdict into appropriate JSON format for flare dendogram?

I have a defaultdict(list) and I used simplejson.dumps(my_defaultdict) in order to output the defaultdict into a JSON format. I am using the HTML code for dendogram from http://bl.ocks.org/mbostock/4063570 but I am trying to make my defaultdict information into the format of the JSON file the author is using. This JSON file is named: /mbostock/raw/4063550/flare.JSON and it's found in this link: http://bl.ocks.org/mbostock/raw/4063550/flare.json.
So here is my defaultdict data:
my_defaultdict = {5: ['child10'], 45: ['child92', 'child45'], 33:['child38']}
json_data = simplejson.dumps(my_defaultdict)
so my current json_data looks like this:
{
"5": [
"child10"
],
"45": [
"child92",
"child45"
],
"33": [
"child38"
]
}
So in my understanding the numbers would be the corresponding "name":"5" and then my JSON format file would also have the children as "children". As what it is right now, my JSON format output doesn't run in the HTML code of the dendogram.
The expected outcome would be like this:
{
"name": "flare",
"children": [
{
"name": "5",
"children": [
{
"name": "child10", "size": 5000},
]
{
"name": "45",
"children": [
{"name": "child92", "size": 3501},
{"name": "child45", "size": 3567},
]
},
{
"name": "33",
"children": [
{"name": "child38", "size": 8044}
]
}
}
Edit:
The answer of #martineau works, but it's not exactly what I want. I start with a defaultdict(list) and the desired output, as above should have the "children" as a list of dicts whereas with martineau kind answer, the "children" it's just a list. If anybody can add something to that to make it work it would be great. Don't worry about the "size" variable, this can be ignored for now.
You need to make a new dictionary from your defaultdict. The children in your example code is just a list of strings, so I don't know where the "size" of each one comes from so just changed it into a list of dicts (which don't have a an entry for a "size" key).
from collections import defaultdict
#import simplejson as json
import json # using stdlib module instead
my_defaultdict = defaultdict(list, { 5: ['child10'],
45: ['child92', 'child45'],
33: ['child38']})
my_dict = {'name': 'flare',
'children': [{'name': k,
'children': [{'name': child} for child in v]}
for k, v in my_defaultdict.items()]}
json_data = json.dumps(my_dict, indent=2)
print(json_data)
Output:
{
"name": "flare",
"children": [
{
"name": 33,
"children": [
{
"name": "child38"
}
]
},
{
"name": 5,
"children": [
{
"name": "child10"
}
]
},
{
"name": 45,
"children": [
{
"name": "child92"
},
{
"name": "child45"
}
]
}
]
}
I solved by using this: How to convert defaultdict to dict?
For future people that may search for it. I achieved by transforming the defaultdict into a commom dictionary just calling:
b = defaultdict(dict)
a = dict(b)
Then the JSON could recognize this structure.
You need to build the dictionary so that it contains the desired 'children' fields. json.dumps does not output data in any predefined schema. Rather, the object passed to json.dumps must already adhere to any structure desired.
Try something like this:
my_defaultdict = {"name": "5",
"children":[ {"name": "child10", "children":[]}]}
print json.dumps(my_defaultdict)

Categories