How to create a function to parse a JSON block? - python

With the below 'food_object' json block, create a function to parse the 'food_object' and provide the two variables 'desired_type' and 'desired_id' that will return the corresponding food to be returned, given provided desired type and id. With the returned result, print out the result in a string with the 'desired_type' variable in a format like this: 'My fruit's name is: apple"
food_object = {
"fruit": [
{
"id": "001",
"name": "apple"
},{
"id": "002",
"name": "orange"
},{
"id": "003",
"name": "banana"
}
],
"vegetable": [
{
"id": "001",
"name": "carrot"
},{
"id": "002",
"name": "broccoli"
},{
"id": "003",
"name": "green beans"
}
]
}
desired_type = "fruit"
desired_id = "001"

You just need to parse the original string with json.loads and then process it like a normal dictionary.
I give you a fully functional example that resolves your concrete problem.
import json
# functions definition
def parse_json_payload(payload: str):
"""
Returns a object from string json payload
"""
parsed = json.loads(original_str)
return parsed
def extract_desired_type(object: dict,desired_type: str):
"""
Returns de desired object type
"""
return object[desired_type]
def extract_desired_id(objects, id: str):
"""
Returns the desired object id if exists.
If not, returns empty object
"""
for element in objects:
if element["id"] == id:
return element
return {}
# main
original_str = """{
"fruit": [
{
"id": "001",
"name": "apple"
},{
"id": "002",
"name": "orange"
},{
"id": "003",
"name": "banana"
}
],
"vegetable": [
{
"id": "001",
"name": "carrot"
},{
"id": "002",
"name": "broccoli"
},{
"id": "003",
"name": "green beans"
}
]
}
"""
def show_example_1():
# Extract fruit with id 001
body = parse_json_payload(original_str)
type_object = extract_desired_type(body, "fruit")
object = extract_desired_id(type_object,"001")
print(object)
def show_example_2():
# Extract vegetable with id 002
body = parse_json_payload(original_str)
type_object = extract_desired_type(body, "vegetable")
object = extract_desired_id(type_object,"002")
print(object)
show_example_1()
print("\n\n")
show_example_2()
Output example:
python3 json_parser.py
{'id': '001', 'name': 'apple'}
{'id': '002', 'name': 'broccoli'}

Use the function loads from the json module to convert a JSON string to a dictionary, then loop over the items of the list json[desired_type] and check for each item if it's id matches the desired_id, if so, return that item's name. If there's no match, return something like not found. Then, use a print to print out the result:
import json
desired_type = "fruit"
desired_id = "001"
json_string = """{
"fruit": [
{
"id": "001",
"name": "apple"
},{
"id": "002",
"name": "orange"
},{
"id": "003",
"name": "banana"
}
],
"vegetable": [
{
"id": "001",
"name": "carrot"
},{
"id": "002",
"name": "broccoli"
},{
"id": "003",
"name": "green beans"
}
]
}"""
jsonobj = json.loads(json_string)
def get_item(desired_type, desired_id):
for item in jsonobj[desired_type]:
if item["id"] == desired_id:
return item["name"]
return "not found"
print("My", desired_type, "'s name is:", get_item(desired_type, desired_id))

Related

How to parse JSON results by condition?

There is JSON and a Python script.
Which displays a list of Companies on the screen.
How to display all Regions for Company[id] ?
{
"data": [
{
"id": 1,
"attributes": {
"name": "Company1",
"regions": {
"data": [
{
"id": 1,
"attributes": {
"name": "Region 1",
}
},
{
"id": 2,
"attributes": {
"name": "Region 2",
}
},
]
}
}
},
{
"id": 2,
"attributes": {
"name": "Company2",
"regions": {
"data": [
{
"id": 1,
"attributes": {
"name": "Region 1",
}
},
{
"id": 2,
"attributes": {
"name": "Region 2",
}
}
]
}
}
},
],
}
Script for all companies.
import os
import json
import requests
BASE_URL = 'localhost'
res = requests.get(BASE_URL)
res_content = json.loads(res.content)
for holding in res_content['data']:
print(holding['id'], holding['attributes']['name'])
How to do the same for displaying the Region for Company[id] ?
Example: Display all Regions for Company 1
Iterate through a list of dictionaries, looking for a dictionary with the key 'name' that has the value 'Company1'. Once it finds that dictionary, it iterates through the list of dictionaries stored under the key 'regions' and prints the value of the key 'name' for each dictionary in that list.
You can try this:
for company in res_content['data']:
if company['attributes']['name'] == 'Company1':
for region in company['attributes']['regions']['data']:
print(region['attributes']['name'])
You just need to delve further down into the res_content object:
for holding in res_content['data']:
print(holding['id'], holding['attributes']['name'])
data = holding['attributes']['regions']['data']
for d in data:
print(' ', d['attributes']['name'])
Output:
1 Company1
Region 1
Region 2
2 Company2
Region 1
Region 2

duplicates in a JSON file based on two attributes

I have a JSON file and that is a nested JSON. I would like to remove duplicates based on two keys.
JSON example:
"books": [
{
"id": "1",
"story": {
"title": "Lonely lion"
},
"description": [
{
"release": false,
"author": [
{
"name": "John",
"main": 1
},
{
"name": "Jeroge",
"main": 0
},
{
"name": "Peter",
"main": 0
}
]
}
]
},
{
"id": "2",
"story": {
"title": "Lonely lion"
},
"description": [
{
"release": false,
"author": [
{
"name": "Jeroge",
"main": 1
},
{
"name": "Peter",
"main": 0
},
{
"name": "John",
"main": 0
}
]
}
]
},
{
"id": "3",
"story": {
"title": "Lonely lion"
},
"description": [
{
"release": false,
"author": [
{
"name": "John",
"main": 1
},
{
"name": "Jeroge",
"main": 0
}
]
}
]
}
]
Here I try to match the title and author name. For example, for id 1 and id 2 are duplicates( as the title is same and author names are also same(the author sequence doesn't matter and no need to consider the main attributes). So, in the output JSON only id:1 or id:2 will remain with id:3. In the final output I need two file.
Output_JSON:
"books": [
{
"id": "1",
"story": {
"title": "Lonely lion"
},
"description": [
{
"release": false,
"author": [
{
"name": "John",
"main": 1
},
{
"name": "Jeroge",
"main": 0
},
{
"name": "Peter",
"main": 0
}
]
}
]
},
{
"id": "3",
"story": {
"title": "Lonely lion"
},
"description": [
{
"release": false,
"author": [
{
"name": "John",
"main": 1
},
{
"name": "Jeroge",
"main": 0
}
]
}
]
}
]
duplicatedID.csv:
1-2
The following method I tried but it is not giving correct results:
list= []
duplicate_Id = []
for data in (json_data['books'])[:]:
elements= []
id = data['id']
title = data['story']['title']
elements.append(title)
for i in (data['description'][0]['author']):
name = (i['name'])
elements.append(name)
if not list:
list.append(elements)
else:
for j in list:
if set(elements) == set(j):
duplicate_Id.append(id)
elements = []
The general idea is to:
Get the groups identified by some function that collects duplicates.
Then return the first entry of each group, ensuring no duplicates.
Define the key function as the sorted list of authors and. As the list of authors is by definition the unique key, but may appear in any order.
import json
from itertools import groupby
j = json.load(books)
def transform(books):
groups = [list(group) for _, group in groupby(books, key=getAuthors)]
return [group[0] for group in groups]
def getAuthors(book):
authors = book['description'][0]['author']
return sorted([author['name'] for author in authors])
print(transform(j['books']))
If we wanted to get the duplicates, then we do the same computation, but return any sublist with length > 1 as this is by our definition duplicated data.
def transform(books):
groups = [list(group) for _, group in groupby(books, key=getAuthors)]
return [group for group in groups if len(group) > 1]
Where j['books'] is the JSON you gave enclosed in an object.

Find a list inside of json data with regular expressions

I am trying to find a list inside of JSON data with RegEx. Here is my code:
import requests
from bs4 import BeautifulSoup
import re
import json
source = requests.get('https://www.tripadvisor.ch/Hotel_Review-g188113-d228146-Reviews-Coronado_Hotel-Zurich.html#REVIEWS').text
soup = BeautifulSoup(source, 'lxml')
pattern = re.compile(r'window.__WEB_CONTEXT__={pageManifest:(\{.*\})};')
script = soup.find("script", text=pattern)
dictData = pattern.search(script.text).group(1)
jsonData = json.loads(dictData)
pattern2 = re.compile(r'^\"[0-9]*\":{\"data\":{\"locations\":(.*)},')
data_list = pattern2.search(str(jsonData)).group(1)
print(data_list)
With this regular expression pattern2 = re.compile(r'^\"[0-9]*\":{\"data\":{\"locations\":(.*)},') I want to find the value (list) of locations, but I get an error AttributeError: 'NoneType' object has no attribute 'group'.
The part of JSON data that I want to find looks like this:
"3960485871": {
"data": {
"locations": [
{
"detail": {
"hotel": {
"aliases": [
{
"id": 1099146,
"locale": "de",
"score": 390000,
"text": "hotel coronado"
},
{
"id": 1261196,
"locale": "es",
"score": 260000,
"text": "hotel coronado"
},
{
"id": 261321,
"locale": null,
"score": 112500,
"text": "coronado hotel z\u00fcrich"
}
],
"details": {
"numRooms": 40
}
},
"priceRange": {
"maximum": 212,
"minimum": 133
}
},
"formerName": null,
"locationId": 228146,
"neighborhoods": [],
"parents": [
{
"locationId": 188113,
"name": "Z\u00fcrich",
"placeType": "MUNICIPALITY"
},
{
"locationId": 188111,
"name": "Kanton Z\u00fcrich",
"placeType": "CANTON"
},
{
"locationId": 188045,
"name": "Schweiz",
"placeType": "COUNTRY"
},
{
"locationId": 4,
"name": "Europa",
"placeType": "CONTINENT"
},
{
"locationId": 1,
"name": "Welt",
"placeType": null
}
]
}
]
}
},
Try this (input data reduced as it was too big)
jsonData = {
"3960485871": {
"data": {
"locations": [
{
"detail": {},
"formerName": None,
"locationId": 228146,
"neighborhoods": [],
"parents": []
}
]
}
},
}
def find_recursive(data, type_):
# If we found what we are looking for, return it
if isinstance(data, type_):
return data
# If we didn't find it, recursively look for it
# Lists and tuples
if isinstance(data, (list, tuple)):
for item in data:
item = find_recursive(item, type_)
if item is not None:
return item
# Dicts
elif isinstance(data, dict):
for item in data.values():
item = find_recursive(item, type_)
if item is not None:
return item
# Add here other containers that you want to recursively look for
# If we weren't able to find it recursively, return None
return None
find_recursive(jsonData, list)
Usage: find_recursive(DATA, TYPE) where DATA is the nested containers and TYPE the python type you want to find. It does accept lists and dicts as nested containers but it could be extended to others (such as set) just by iterating over their items and returning them if they are not None. You can use a single if for multiple types like I did with list and tuple in case they behave the same.

How do i make this JSON structure work as intended?

I have some data from a project where the variables can change from motorcycle and car. I need to get the name out of them and that value is inside the variable.
This is not the data i will be using but it has the same structure, the "official" data is some persional information so i changed it to some random values. I can not change the structure of the JSON data since this is the way the serveradmins decided to structure it for some reason.
This is my python code:
import json
with open('exampleData.json') as j:
data = json.load(j)
name = 0
Vehicle = 0
for x in data:
print(data['persons'][x]['name'])
for i in data['persons'][x]['things']["Vehicles"]:
print(data['persons'][x]['things']['Vehicles'][i]['type']['name'])
print("\n")
This is my Json data i extracted from the file "ExampleData.json"(sorry for long but it is kinda complex and necessary to understand the problem):
{
"total": 2,
"persons": [
{
"name": "Sven Svensson",
"things": {
"House": "apartment",
"Vehicles": [
{
"id": "46",
"type": {
"name": "Kawasaki ER6N",
"type": "motorcyle"
},
"Motorcycle": {
"plate": "aaa111",
"fields": {
"brand": "Kawasaki",
"status": "in shop"
}
}
},
{
"id": "44",
"type": {
"name": "BMW m3",
"type": "Car"
},
"Car": {
"plate": "bbb222",
"fields": {
"brand": "BMW",
"status": "in garage"
}
}
}
]
}
},
{
"name": "Eric Vivian Matthews",
"things": {
"House": "House",
"Vehicles": [
{
"id": "44",
"type": {
"name": "Volvo XC90",
"type": "Car"
},
"Car": {
"plate": "bbb222",
"fields": {
"brand": "Volvo",
"status": "in garage"
}
}
}
]
}
}
]
}
I want it to print out something like this :
Sven Svensson
Bmw M3
Kawasaki ER6n
Eric Vivian Matthews
Volvo XC90
but i get this error:
print(data['persons'][x]['name'])
TypeError: list indices must be integers or slices, not str
Process finished with exit code 1
What you need is
for person in data["persons"]:
for vehicle in person["things"]["vehicles"]:
print(vehicle["type"]["name"])
type = vehicle["type"]["type"]
print(vehicle[type]["plate"])
Python for loop does not return the key but rather an object here:
for x in data:
Referencing an object as key
print(data['persons'][x]['name'])
Is causing the error
What you need is to use the returning json object and iterate over them like so:
for x in data['persons']:
print(x['name'])
for vehicle in x['things']['Vehicles']:
print(vehicle['type']['name'])
print('\n')

python json(how to read mulpite id in comple

I have json file i what to read all the values
data=""" {"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
{
"maps":[
{"id":"apple","iscategorical":"0"},
{"id":"ball","iscategorical":"0"}
],
"mask":{"id1":"aaaaa"},
"mask":{"id1":"bbb"},
"mask":{"id1":"cccccc"},
"om_points":"value",
"parameters":
{"id":"valore"}
}"""
out = json.loads(data)
how to get all values
firstname
lastname
mask.id1
map.id
output:
[(firstname_vaues,lastname_values,mask.id1,map.id)
(firstname_vaues,lastname_values,mask.id1,map.id) ......]
please help me
First thing, there are two json objects in your data string. So you cannot use json.loads(data). You can seperate them by a charcter like ";" . Then split the string and use json.loads on each of them.Use following code.
import json
data=""" {
"employees": [{
"firstName": "John",
"lastName": "Doe"
}, {
"firstName": "Anna",
"lastName": "Smith"
}, {
"firstName": "Peter",
"lastName": "Jones"
}]
};{
"maps": [{
"id": "apple",
"iscategorical": "0"
}, {
"id": "ball",
"iscategorical": "0"
}],
"mask": {
"id1": "aaaaa"
},
"mask": {
"id1": "bbb"
},
"mask": {
"id1": "cccccc"
},
"om_points": "value",
"parameters": {
"id": "valore"
}
}"""
splitdata = data.split(';')
datatop = json.loads(splitdata[0])
databottom = json.loads(splitdata[1])
Then you can access required fields as follows
print(datatop['employees'][0]['firstName'])
print(datatop['employees'][0]['lastName'])
print(databottom['mask']['id1'])
print(databottom['maps'][0]['id'])

Categories

Resources