Parsing a json output with dictionary values - python-3.x

Hello my JSON file looks like this :
{
'hits' : 3,
'results' : [{
'part' : {
'id' : '123',
'name' : 'to go',
'manu' :{
'name' :'xyz'
}
}
}]
}
how do i get :
hits : 3
results_id : 123
results_name : to go
manu_name : xyz
Looking to write a python key-value pair for a loop... Not getting please advise.
My keys are hits and results

Try this
dout = {}
#din = json.load("file.json") #read from json
din = {'hits' : 3, 'results' : [{'part' : {'id' : '123', 'name' : 'to go', 'manu' :{ 'name' :'xyz'}}}]}
for part in din['results']:
for p, data in part.items():
dout['hits'] = din['hits']
dout['results_id'] = data['id']
dout['results_name'] = data['name']
dout['manu_name'] = data['manu']['name']
print(dout)

First of all, update the string as follows to make it valid JSON:
{"hits" : 3, "results" : [{"part" : {"id" : "123", "name" : "to go", "manu" :{ "name" :"xyz"}}}]}
Assuming that's the content of your text file, proceed as follows:
import json
data = {}
with open("stackOverflow/brooklinite81.json") as json_file:
data = json.load(json_file)
data
which renders:
{'hits': 3, 'results': [{'part': {'id': '123', 'name': 'to go', 'manu': {'name': 'xyz'}}}]}
Now, you can create a dictionary the way you wanted it as follows:
res = {'hits' :data['hits'],
'results_id': data['results'][0]['part']['id'],
'manu': data['results'][0]['part']['manu']['name']
}
res
which renders as:
{'hits': 3, 'results_id': '123', 'manu': 'xyz'}

Related

Return specific values from a nested dictionary with a generator function

I have a list of dict containing nested dict which looks like below. I would like to use generators and yield to go over reviews list of dict and return all rating given a specific user value. For example "user" : "A11" has two rating records. I would like to have these returned as dict.
data = [{ "product_id" : "123",
"size" : "L",
"color" : "blue",
"reviews" : [
{ "user" : "A11", "rating" : "score1" },
{ "user" : "Z99", "rating" : "score" }] },
{ "product_id" : "987",
"size" : "M",
"color" : "red",
"reviews" : [
{ "user" : "A11", "rating" : "score2" },
{ "user" : "X55", "rating" : "score" }] }
]
I have the following generator but it is basically returning all rating values regardless of the user. How can I make the function to filter the values to a specific user ?
def user_rating(nest, kv):
if isinstance(nest, list):
for i in nest:
for x in user_rating(i, kv):
yield x
elif isinstance(nest, dict):
if kv in nest:
yield nest[kv]
for j in nest.values():
for x in user_rating(j, kv):
yield x
print(list(user_rating(data, 'rating')))
A little modify should be enough:
def user_rating(nest, kv):
if isinstance(nest, list):
for i in nest:
yield from user_rating(i, kv)
elif isinstance(nest, dict):
if nest.get('user') == kv: # <----- here
yield nest # <---- and here
for j in nest.values():
yield from user_rating(j, kv)
print(list(user_rating(data, 'A11')))
#[{'user': 'A11', 'rating': 'score1'}, {'user': 'A11', 'rating': 'score2'}]
Btw you can use yield from to ... well, yield from another generator instead of using a for loop

How do I merge dictionaries in list that have equal value and concate values that are not equal?

there is list of dictionaries:
[
{
"id" : 2.0,
"code" : "12345"
},
{
"id" : 2.0,
"code" : "23456"
},
{
"id" : 4.0,
"code" : "6767"
},
{
"id" : 5.0,
"code" : "567"
},
{
"id" : 4.0,
"code" : "55657"
}
]
I want to merge dict that have common id,
then i want to have this list as you see:
[
{
"id" : 2.0,
"code" : "12345,23456"
},
{
"id" : 4.0,
"code" : "6767,55657"
},
{
"id" : 5.0,
"code" : "567"
}
]
is there any faster way can check all of this in for loop ?
you can build a dictionary that has as key your id value and the values are a list of codes with commune id, then you can build your desired output using a list comprehension:
from collections import defaultdict
result = defaultdict(list)
for d in my_list:
result[d['id']].append(d['code'])
final_list = [{'id': k, 'code': ', '.join(v)} for k, v in result.items()]
print(final_list)
output:
[{'id': 2.0, 'code': '12345, 23456'},
{'id': 4.0, 'code': '6767, 55657'},
{'id': 5.0, 'code': '567'}]

while nesting a dictionary inside a list, getting a TypeError : string indices must be integers

friend_0 = {
'first_name' : 'wong',
'last_name' : 'cap bawong',
'age' : 16,
}
friend_1 = {
'first_name' : 'lele',
'last_name' : 'cap meong',
'age' : 46,
}
friend_2 = {
'first_name' : 'kucing',
'last_name' : 'nan indah',
'age' : 18
}
people = [friend_0, friend_1, friend_2]
for person in people:
for k in person.keys():
**friend = f"{k['first_name'].title()} {k['last_name'].title()}"**
print (f"\nName: {friend}")
print (f"\tAge: {k['age']}")
i got error in the line of: friend = f"{k['first_name'].title()}
{k['last_name'].title()}"
FileType error - string indices must be integers
try this:
for person in people:
friend = f"{person['first_name'].title()} {person['last_name'].title()}"
print(f"\nName: {friend}")
print(f"\tAge: {person['age']}")

How to sort response in Ready API using groovy in ascending and descending order

I have gone through various articles but didn't find any simple way to sort the API response in ascending or descending order using groovy. Can someone please help on this?
import groovy.json.JsonSlurper
def inputJson = '''{
"status" : "success",
"locale" : "",
"data" : {
"periods" : [
{
"payCycleId" : "custompayperiod",
"sequence" : 1,
"cycleStartDate" : "2018-10-01",
"cycleEndDate" : "2018-10-08"
},
{
"payCycleId" : "custompayperiod",
"sequence" : 2,
"cycleStartDate" : "2018-10-09",
"cycleEndDate" : "2018-10-16"
}
]
}
}
Want to sort above response based on sequence.
There are a lot of ways.
For example:
def json = new JsonSlurper().parseText(inputJson)
//Descending
json.data.periods = json.data.periods.toSorted { a, b -> b.sequence <=> a.sequence }
//Ascending
//json.data.periods = json.data.periods.toSorted { a, b -> a.sequence <=> b.sequence }
String output = JsonOutput.prettyPrint(JsonOutput.toJson(json))

How to get json result with parent - child relation?(see details)

I have two json one is parent and another is child, I want to merge both. Please help. See the example below
Two tables are as below.
var parent = [{id : 1, name : 'India'},
{id : 2, name : 'USA'},
{id : 3, name : 'Japan'},
{id : 4, name : 'UK'}]
var child = [{id: 1, parentId: 1, city : 'Ahmedabad', population:100},
{id: 2, parentId: 1, city : 'Mumbai', population:200},
{id: 3, parentId: 2, city : 'NewYork', population:300},
{id: 4, parentId: 2, city : 'Chicago', population:400},
{id: 5, parentId: 3, city : 'Tokyo', population:500}]
I want to result like below
var result =
[{id : 1, name : 'India', city:[{name : 'Ahmedabad', population:100},{name : 'Mumbai', population:200}]},
{id : 2, name : 'USA', city:[{name : 'NewYork', population:300},{name : 'Chicago', population:400}]},
{id : 3, name : 'Japan', city:[{name : 'Tokyo', population:500}]},
{id : 4, name : 'UK', city:[]}
]
var result =JSON.parse(JSON.stringify(parent));
result.map(function (d, i) {
d.city = (child.filter(function (d1) {
if (d1.parentId == d.id) {
return d1;
}
})).map(function(d2){
return {city:d2.city,population:d2.population}
});
})
Now result variable contains your expected result.

Resources