json parsing in python with condition - python

Could you give me some advice about parsing list from list of dictionary with some conditions in Python3.
From below list of json, I want to extract the max timestamp for each "id".
So the final output I want to have is like
[{
"id": 1,
"value": {
"val1": 400000000,
"val2": 750000000
},
"timestamp": 1600957822.2510917
},
{
"id": 2,
"value": {
"val1": 400000000,
"val2": 750000000
},
"timestamp": 1600958083.618805
}]
Is there any way I can do? Thanks in advance
[
{
"id": 1,
"value": {
"val1": 400000000,
"val2": 750000000
},
"timestamp": 1600957822.2510917
},
{
"id": 2,
"value": {
"val1": 400000000,
"val2": 750000000
},
"timestamp": 1600957857.3018847
},
{
"id": 2,
"value": {
"val1": 400000000,
"val2": 750000000
},
"timestamp": 1600958027.4114041
},
{
"id": 2,
"value": {
"val1": 400000000,
"val2": 750000000
},
"timestamp": 1600958083.618805
}]

If it's list of dictionaries (as spotted in the comments) here is a way to parse it and retrieve a final list of dict:
result = {}
for obj in dict_list:
if obj['id'] in result:
if result[obj['id']]['timestamp'] < obj['timestamp']:
result[obj['id']]['timestamp'] = obj['timestamp']
else:
result[obj['id']] = obj
[x for x in result.values()]

Here is an example of parsing:
import json
# load json
data = json.loads(source)
result = {}
# iterate over json objects
for d in data:
# check whether id is already in result map or not
if d['id'] in result:
# if id already in result, compare timestamps
if d['timestamp'] > result[d['id']]:
result[d['id']] = d['timestamp']
else:
# if id not in result, add id / timestamp pair
result[d['id']] = d['timestamp']
print (result)

Related

finding a specific object within duplicate element names, python with json

I'm looking to grab the displayValue from objectAttributeValues where the objectTypeAttributeId = 14
there are multiple arrays like this, and the position of objectTypeAttributeId = 14 isn't always the same. how do I loop over every array to get that specific displayValue?
I've got something that looks through every possible array, but I want to clean it up.
sample json:
{
"objectEntries": [{
"attributes": [{
"id": "5210",
"objectAttributeValues": [{
"displayValue": "10/Nov/22 3:33 PM",
"referencedType": false,
"searchValue": "2022-11-10T15:33:49.298Z",
"value": "2022-11-10T15:33:49.298Z"
}],
"objectId": "1201",
"objectTypeAttributeId": "12"
},
{
"id": "5213",
"objectAttributeValues": [{
"displayValue": "02f9ed75-b416-49d0-8515-0601581158e5",
"referencedType": false,
"searchValue": "02f9ed75-b416-49d0-8515-0601581158e5",
"value": "02f9ed75-b416-49d0-8515-0601581158e5"
}],
"objectId": "1201",
"objectTypeAttributeId": "14"
},
{
"id": "5212",
"objectAttributeValues": [{
"displayValue": "",
"referencedType": false,
"searchValue": "",
"value": ""
}],
"objectId": "1201",
"objectTypeAttributeId": "11"
}
]
},
{
"attributes": [{
"id": "4263",
"objectAttributeValues": [{
"displayValue": "427904c5-e2c8-4735-bc38-4013928cd043",
"referencedType": false,
"searchValue": "427904c5-e2c8-4735-bc38-4013928cd043",
"value": "427904c5-e2c8-4735-bc38-4013928cd043"
}],
"objectId": "1011",
"objectTypeAttributeId": "14"
},
{
"id": "4262",
"objectAttributeValues": [{
"displayValue": "",
"referencedType": false,
"searchValue": "",
"value": ""
}],
"objectId": "1011",
"objectTypeAttributeId": "11"
}
]
}
]
}
for this sample query, the values would be:
02f9ed75-b416-49d0-8515-0601581158e5
427904c5-e2c8-4735-bc38-4013928cd043
this is my code so far, and would like to make it for efficient:
from jira import JIRA
import requests
import json
base_url = "url"
auth = basic_auth=('user', 'pass')
headers = {
"Accept": "application/json"
}
pages = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for page in pages:
response = requests.request("GET",base_url + '?page=' + str(page),headers=headers,auth=auth)
all_output = json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": "))
output_dict = json.loads(response.text)
output_list = output_dict["objectEntries"]
for outputs in output_list:
print(outputs["attributes"][0]["objectId"])
print(outputs["name"])
print(outputs["objectKey"])
if len(outputs["attributes"][0]["objectAttributeValues"][0]["displayValue"])==36:
print(outputs["attributes"][0]["objectAttributeValues"][0]["displayValue"])
if len(outputs["attributes"][1]["objectAttributeValues"][0]["displayValue"])==36:
print(outputs["attributes"][1]["objectAttributeValues"][0]["displayValue"])
if len(outputs["attributes"][2]["objectAttributeValues"][0]["displayValue"])==36:
print(outputs["attributes"][2]["objectAttributeValues"][0]["displayValue"])
if len(outputs["attributes"][3]["objectAttributeValues"][0]["displayValue"])==36:
print(outputs["attributes"][3]["objectAttributeValues"][0]["displayValue"])
if len(outputs["attributes"][4]["objectAttributeValues"][0]["displayValue"])==36:
print(outputs["attributes"][4]["objectAttributeValues"][0]["displayValue"])
print('\n')
Any suggestions would be appreciated!!
If structure is not changing then this can the solution It will iterate over all objects and add displayValue in search_values list
display_values = []
for object_entries in output_dict.get("objectEntries", []):
for attribute in object_entries.get("attributes"):
if attribute.get("objectTypeAttributeId") == "14":
for object_attr in attribute.get("objectAttributeValues", []):
if object_attr.get("displayValue") not in display_values:
display_values.append(object_attr.get("displayValue"))
print(display_values)
You could browse your JSON dict and proceed each entries until you get the one(s) you are interested in.
# lets browse top level entries of your array
for e1 in outputs["objectEntries"]:
# for each of those entries, browse the entries in the attribute section
for e2 in e1["attributes"]:
# does the entry match the rule "14"? If not, go to the next one
if (e2["objectTypeAttributeId"] != 14):
continue
# print the current entry's associated value
for attr in e2["objectAttributeValues"]
print(attr["displayValue"])
You can iterate over your dict and check if the values matches with a function like this:
def get_display_value(my_dict, value):
results = []
for objectEntries in my_dict['objectEntries']:
for attributes in objectEntries['attributes']:
if int(attributes['objectTypeAttributeId']) == value:
results.append(attributes['objectAttributeValues'][0]['displayValue'])
return results
Using the function:
results = get_display_value(my_dict, 14)
print(results)
Outputs:
['02f9ed75-b416-49d0-8515-0601581158e5', '427904c5-e2c8-4735-bc38-4013928cd043']
Edit: now returning all match values instead of only the first one.

Creating a custom json from existing json

I have Json something like below
Input Json
"blocks": [
{
"key": "",
"text": "Contents",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [
{
"offset": 0,
"length": 8,
"style": "BOLD"
}
],
"entityRanges": [],
"data": {}
},
{
"key": "",
"text": "1.\u00a0\u00a0\u00a0\u00a0 Completed\n Activities & Accomplishments\u00a0 1",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [
{
"offset": 0,
"length": 49,
"key": 0
}
],
"data": {}
},
{
"key": "",
"text": "2.\u00a0\u00a0\u00a0\u00a0 Planned Activities for\n Next Reporting Period\u00a0 3",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [
{
"offset": 0,
"length": 55,
"key": 1
}
],
"data": {}
},
I am trying to extract "text" key data and want to convert it into new json in the key value format
I am able to extract text properly now I just wanna know how to separate numeric from letters successfully
def jsontojson():
with open('C:\Extraction\Docs\TMS TO 692M15-22-F-00073 Monthly Status _ Financial Report July 2022.json') as json_file:
# json1=json_file.read()
json1=json.load(json_file)
value=""
for dict1 in json1["blocks"]:
# print(dict1)
for key in dict1:
if key=="text":
value+=dict1[key]
dict2={}
d=value.split()
print("Value of d",d)
if str(d).isdigit():
dict2['key1']=d
else:
dict2['desciption']=d
print("Dictionary is",dict2['key'])
For the above code it gives me Key error : key1
Let me know where i am wrong or what I need to do so that i can get the Output
Expected OUTPUT
[
{
"key": "",
"text": "Contents"
},
{
"key": "1.",
"text": "Completed Activities & Accomplishments"
},
{
"key": "2.",
"text": "Planned Activities for Next Reporting Period"
},
]
Try (json1 contains the data from your question):
import re
out = []
for d in json1["blocks"]:
num = re.search(r"^(\d+\.)\s*(.*)", d["text"].replace("\n", ""))
out.append(
{
"key": num.group(1) if num else "",
"text": (num.group(2) if num else d["text"]).rsplit(maxsplit=1)[0],
}
)
print(out)
Prints:
[
{"key": "", "text": "Contents"},
{"key": "1.", "text": "Completed Activities & Accomplishments"},
{"key": "2.", "text": "Planned Activities for Next Reporting Period"},
]
Another and easy way is (if your first list is called "Mylist" :
new_list =[]
for dic in Mylist:
new_list.append({'key':dic['key'],
'text':dic['text']})

Find a value in a list of dictionaries

I have the following list:
{
"id":1,
"name":"John",
"status":2,
"custom_attributes":[
{
"attribute_code":"address",
"value":"st"
},
{
"attribute_code":"city",
"value":"st"
},
{
"attribute_code":"job",
"value":"test"
}]
}
I need to get the value from the attribute_code that is equal city
I've tried this code:
if list["custom_attributes"]["attribute_code"] == "city" in list:
var = list["value"]
But this gives me the following error:
TypeError: list indices must be integers or slices, not str
What i'm doing wrong here? I've read this solution and this solution but din't understood how to access each value.
Another solution, using next():
dct = {
"id": 1,
"name": "John",
"status": 2,
"custom_attributes": [
{"attribute_code": "address", "value": "st"},
{"attribute_code": "city", "value": "st"},
{"attribute_code": "job", "value": "test"},
],
}
val = next(d["value"] for d in dct["custom_attributes"] if d["attribute_code"] == "city")
print(val)
Prints:
st
Your data is a dict not a list.
You need to scan the attributes according the criteria you mentioned.
See below:
data = {
"id": 1,
"name": "John",
"status": 2,
"custom_attributes": [
{
"attribute_code": "address",
"value": "st"
},
{
"attribute_code": "city",
"value": "st"
},
{
"attribute_code": "job",
"value": "test"
}]
}
for attr in data['custom_attributes']:
if attr['attribute_code'] == 'city':
print(attr['value'])
break
output
st

Group and sort JSON array of dictionaries by repeatable keys in Python

I have a json that is a list of dictionaries that looks like this:
I am getting it from MySQL with pymysql
[{
"id": "123",
"name": "test",
"group": "test_group"
},
{
"id": "123",
"name": "test",
"group": "test2_group"
},
{
"id": "456",
"name": "test2",
"group": "test_group2"
},
{
"id": "456",
"name": "test2",
"group": "test_group3"
}]
I need to group it so each "name" will have just one dict and it will contain a list of all groups that under this name.
something like this :
[{
"id": "123",
"name": "test",
"group": ["test2_group", "test_group"]
},
{
"id": "456",
"name": "test2",
"group": ["test_group2", "test_group3"]
}]
I would like to get some help,
Thanks !
You can use itertools.groupby for grouping of data.
Although I don't guarantee solution below to be shortest way but it should do the work.
# Your input data
data = []
from itertools import groupby
res = []
key_func = lambda k: k['id']
for k, g in groupby(sorted(data, key=key_func), key=key_func):
obj = { 'id': k, 'name': '', 'group': []}
for group in g:
if not obj['name']:
obj['name'] = group['name']
obj['group'].append(group['group'])
res.append(obj)
print(res)
It should print the data in required format.

how do i sort through a json converted to list?

suppose I had an object like:
[
{
"id": 2,
"name": "cat"
},
{
"id": 6,
"name": "dog"
},
{
"id": 8,
"name": "horse"
},
{
"id": 10,
"name": "turtle"
}
]
I wish to write a function that can take an input id and tell me the associated name.
if animal_list was assigned that list, how would I find which animal was associated with 6? animal_list[id==6]?
It would be best if you could convert the list into a dictionary as #ShadowRanger said, but if you can't you could use list comprehensions with an if statement like this:
my_list = [
{
"id": 2,
"name": "cat"
},
{
"id": 6,
"name": "dog"
},
{
"id": 8,
"name": "horse"
},
{
"id": 10,
"name": "turtle"
}
]
def get_by_id(the_list, id):
found = [dict for dict in the_list if dict['id'] == id]
if found:
return found[0]
return None
print(get_by_id(my_list, 6))
# will output: {'id': 6, 'name': 'dog'}
animal_list is the list you gave in your question
animal_list = [
{
"id": 2,
"name": "cat"
},
{
"id": 6,
"name": "dog"
},
{
"id": 8,
"name": "horse"
},
{
"id": 10,
"name": "turtle"
}
]
def get_animal(id):
found = 0
for i in animal_list:
if animal_list[i]["id"] == id :
found = 1
print animal_list[i]["name"]
if found == 0:
print "animal not found"
You can import your data as a JSON and work with it using a dict structure.
I've created a function that will return the animal name if there's a valid key, and none if key doesn't exists.
Code:
s = '[{"id": 2,"name": "cat"},{"id": 6,"name": "dog"},{"id": 8,"name": "horse"},{"id": 10,"name": "turtle"}]'
def search_animal(s, num):
import json
data = json.loads(s)
for d in data:
if d['id'] == num:
print(d['name'])
search_animal(s, 2)
search_animal(s, 6)
Outputs:
cat
dog
list = [
{
"id": 2,
"name": "cat"
},
{
"id": 6,
"name": "dog"
},
{
"id": 8,
"name": "horse"
},
{
"id": 10,
"name": "turtle"
}
]
id = input("Enter ID..! ")
for data in list:
if data.get('id') == id:
print data.get('name')

Categories