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.
Related
I am trying to extract the value of a key that is nested in an anonymous JSON block. This is what the JSON block looks like after result:
"extras": [
{
"key": "alternative_name",
"value": "catr"
},
{
"key": "lineage",
"value": "This dataset was amalgamated, optimised and published by the Spatial hub. For more information visit www.spatialhub.scot."
},
{
"key": "ssdi_link",
"value": "https://www.spatialdata.gov.scot/geonetwork/srv/eng/catalog.search#/metadata/4826c148-c1eb-4eaa-abad-ca4b1ec65230"
},
{
"key": "update_frequency",
"value": "annually"
}
],
What I am trying to do is extract the value annually but I can't use index because some other datasets have more keys under the extras section. I am trying to write a jsonpath expression that extracts value where key is update_frequency
So far what I have tried is:
$.result.extras[*].value[?(key='update_frequency')]
And still no luck.
Any idea what could be wrong?
This should work:
$.result.extras[?(#.key=="update_frequency")].value
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
I currently have a json file that looks like this....
{
"data": [
{
"tag": "cashandequivalents",
"value": 10027000000.0
},
{
"tag": "shortterminvestments",
"value": 101000000.0
},
{
"tag": "accountsreceivable",
"value": 4635000000.0
},
{
"tag": "netinventory",
"value": 1386000000.0
}...
but what I am trying to get to is this
{
"cashandequivalents": 10027000000.0,
"shortterminvestments":101000000.0 ,
"accountsreceivable":4635000000.0,
"netinventory":1386000000.0
}
I just don't know how to go about this.
Maybe there is an easier way, but this seems the most logical to me because the next step is writer.writerow to csv
So eventually the csv will look like
cashandequivalents | shortterminvestments | accountsreceivable | netinventory
100027000000 101000000000 46350000000 13860000000
########### ############ ########### ...........
(writer.writeheader will be done outside of the loop so I am only writing the values, not the "tags")
Thanks
A naive solution:
import json
json_data = {
"data": [
{
"tag": "cashandequivalents",
"value": 10027000000.0
},
{
"tag": "shortterminvestments",
"value": 101000000.0
},
{
"tag": "accountsreceivable",
"value": 4635000000.0
},
{
"tag": "netinventory",
"value": 1386000000.0
}
]
}
result = dict()
for entry in json_data['data']:
result[entry['tag']] = entry['value']
print json.dumps(result, indent=4)
Output
{
"shortterminvestments": 101000000.0,
"netinventory": 1386000000.0,
"accountsreceivable": 4635000000.0,
"cashandequivalents": 10027000000.0
}
The easiest and cleanest way to do this is with a dictionary comprehension.
d = {
"data": [
{
"tag": "cashandequivalents",
"value": 10027000000.0
},
{
"tag": "shortterminvestments",
"value": 101000000.0
},
{
"tag": "accountsreceivable",
"value": 4635000000.0
},
{
"tag": "netinventory",
"value": 1386000000.0
}
]
}
newDict = {i['tag']: i['value'] for i in d['data']}
# {'netinventory': 1386000000.0, 'shortterminvestments': 101000000.0, 'accountsreceivable': 4635000000.0, 'cashandequivalents': 10027000000.0}
This iterates through the list that is contained within the "data" key of your original dictionary and creates a new one inline with the key being the tag value of each and the value being the value for each during the iterations.
Basically I'm generating a json Terraform file from a text file, but I can't get it to format in the correct way:
I want the finished Terraform file to look like this:
{
"resource": {
"aws_route53_record": {
"analytics": {
"name": "analytics",
"records": ["1.2.3.4"],
"ttl": "1800",
"type": "A"
},
"analytics-test": {
"name": "analytics-test",
"records": ["1.2.3.4"],
"ttl": "300",
"type": "A"
}
}
}
}
which is the format Terraform requires to parse json.
So I load the text file in Python, and iterate over each line producing a list of lists that look like so:
records = [["analytics", "1.2.3.4", "1800", "A"],["analytics-test", "1.2.3.4", "300", "A"]]
My code to generate the file at the moment looks like this
I create a dict placeholder containing top level variable like so:
json_object = {'resource': {'aws_route53_record': None}}
Then I look through records and assign the appropriate values:
for each_list in data:
terrarecord = {
each_list[0]:{
"name": each_list[0],
"type": each_list[2],
"ttl": each_list[1],
"records": [each_list[3].replace('\n', '')]
}
}
record_holder.append(terrarecord)
The record_holder object is an empty list that I then use to fill in the json_objects like so:
json_object['resource']['aws_route53_record'] = record_holder
What this gives me in the finished file is:
{
"resource": {
"aws_route53_record": [{
"analytics": {
"ttl": "1800",
"records": ["173.194.245.129"],
"name": "analytics",
"type": "A"
}
}, {
"analytics-test": {
"ttl": "300",
"records": ["130.211.89.168"],
"name": "analytics-test",
"type": "A"
}
}]
}
}
So would there be an easier way to do this without adding the extra [] and {}s that my little loop does?
Why are you creating the intermediate list when you want the dictionary?
terrarecord = {}
for each_list in data:
terrarecord[each_list[0]] = {
"name": each_list[0],
"type": each_list[2],
"ttl": each_list[1],
"records": [each_list[3].replace('\n', '')]
}
}
json_object['resource']['aws_route53_record'] = terrarecord
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.