python - Json data with different keys - python

I am trying to store two run options in Json. My attempt is as below. Is this a sensible way to organise Json object? Also how can I read either of them into tuples? I tried tuple([(item['opt_one'],item['val_one']) for item in config['opts']]) but git a key error. Many thanks for your help.
"opts":[
{
"opt_one": "one_option",
"val_one" : "value_one"
},
{
"opt_two": "two_option",
"val_two" : "value_two"
}
]

# or it can be done in 1 line
print(tuple(map(lambda v: tuple(v.values()), J['opts'])))

import json
j = """
{"opts":[
{
"opt_one": "one_option",
"val_one" : "value_one"
},
{
"opt_two": "two_option",
"val_two" : "value_two"
}
]
}
"""
# note the braces around "opts"
J = json.loads(j) #turns it into a python object
print(J) #see!
# the long way to do it, but you can see the process
R = []
for item in J['opts']:
r = []
for v in item.values():
r.append(v)
R.append(tuple(r))
print(tuple(R)) # solution

Related

Querying a nested JSON file in Python without Indexing

I have the below Json file which I need to query to get the values of the keys inside 'validations' in a list
for example the column_values_not_null output will need to be this:
['lu_name', 'transaction_amount']
"validation_file_name": "ctm",
"connection_type": "s3",
"low_threshold": 500000,
"high_threshold": 1000000,
"frequency": "weekly",
"validations": [
{
"columns_to_match_ordered_list" :[
"lu_name",
"site_name",
"transaction_date_time",
"margin",
"transaction_currency_code",
"reversal_indicator_description",
"reversal_amount",
"original_amount"
]
},
{
"column_values_not_null":[
"lu_name",
"transaction_amount"
]
},
{
"column_values_not_duplicate": [
"lu_name",
"response_code_description"
]
}
]
I am able to do the below but I need to do this without using the index value
f = open('test.json')
json_content = json.load(f)
print(json_content['validations'][1]['column_values_not_null'])
Get a list by querying the validations key. The sum( ,[]) are used to flat the list (as required by the condition "without using the index value" if got it right), for details about it with pros and cons see doc.
data = #
def validations(data: dict, key_query: str) -> list:
for k, v in data.items():
if k == 'validations':
return sum(sum([list(d.values()) for d in v if key_query in d], []), [])
print(validations(data, query='column_values_not_null'))
# ['lu_name', 'transaction_amount']

Python remove nested JSON key or combine key with value

I'm receiving json files improperly and am trying to create a temporary fix until the documents come in the proper format. Instead of the value being set to the derivationsValue key, it is being set as a key value pair, so there is an extraneous key. I want to set the the inner value to the outer key.
{
"derivationName": "other_lob_subcd",
"derivationValue": {
"OOP3": "TENANT"
}
}
Given the above json, I want the result to be
{
"derivationName": "other_lob_subcd",
"derivationValue": "TENANT"
}
I could also live with
{
"derivationName": "other_lob_subcd",
"derivationValue": "OOP3-TENANT"
}
or something like that. It just can't be another json element.
Based on #Diana Ayala's answer, I have written this to try solving the problem with variable keys.
for k,v in data['mcsResults']['derivationsOutput']:
if isinstance(k['derivationValue'], dict):
for sk, sv in k['derivationValue']:
k['derivationValue'] = sv
You can use below generic code for your requirement.
import json
filePath = 'file.json'
def getValue(value):
if type(value) is dict:
ans = list(value)[0]
for k in value:
ans += '-'+getValue(value[k])
return ans
return value
def correct(data):
for key in data:
data[key] = getValue(data[key])
return data
if __name__ == "__main__":
with open(filePath) as fp:
data = json.load(fp)
data = correct(data)
print (data)
output:
D:\>python file.py
{'derivationName': 'other_lob_subcd', 'derivationValue': 'OOP3-TENANT'}
For the example given:
import json
with open('inpt.txt') as json_file:
data = json.load(json_file)
data['derivationValue'] = data['derivationValue']['OOP3']
Gives the output:
{'derivationName': 'other_lob_subcd', 'derivationValue': 'TENANT'}
In general, you can look at the solutions here.
You can do something like this:
val = {
"derivationName": "other_lob_subcd",
"derivationValue": {
"OOP3": "TENANT"
}
}
val["derivationValue"] = val["derivationValue"]["OOP3"]
print(val)
This will be the output:
val = {
"derivationName": "other_lob_subcd",
"derivationValue": "TENANT"
}

How to remove the first and last portion of a string in Python?

How can i cut from such a string (json) everything before and including the first [ and everything behind and including the last ] with Python?
{
"Customers": [
{
"cID": "w2-502952",
"soldToId": "34124"
},
...
...
],
"status": {
"success": true,
"message": "Customers: 560",
"ErrorCode": ""
}
}
I want to have at least only
{
"cID" : "w2-502952",
"soldToId" : "34124",
}
...
...
String manipulation is not the way to do this. You should parse your JSON into Python and extract the relevant data using normal data structure access.
obj = json.loads(data)
relevant_data = obj["Customers"]
Addition to #Daniel Rosman answer, if you want all the list from JSON.
result = []
obj = json.loads(data)
for value in obj.values():
if isinstance(value, list):
result.append(*value)
While I agree that Daniel's answer is the absolute best way to go, if you must use string splitting, you can try .find()
string = #however you are loading this json text into a string
start = string.find('[')
end = string.find(']')
customers = string[start:end]
print(customers)
output will be everything between the [ and ] braces.
If you really want to do this via string manipulation (which I don't recommend), you can do it this way:
start = s.find('[') + 1
finish = s.find(']')
inner = s[start : finish]

Python JSON Element Access with 2 responses

I can't find the right search term to come up with an answer to this but I know it's a noob question. I'm accessing an API which returns either:
{
"Items":[
{
"Id":"12",
"Type":"Address",
"Highlight":"564754165545",
}
]
}
or sometimes:
{
"Items":[
{
"Id":"12",
"Type":"BuildingNumber",
"Highlight":"145454479854",
},
{
"Id":"12",
"Type":"Address",
"Highlight":"564754165545",
}
]
}
I need to get the "highlight" element data but only when type is address from a reply.
Thanks for your help and sorry I couldn't work out the name of the multiple rows to find this for myself.
Items is a list of dicts. According to your example, sometimes the list contains one item, and other times it contains two items.
for item in foo['Items']:
if item['Type'] == 'Address':
print (item['Highlight'])
Use following code
new_items = [ j for j in JSON['Items'] if j.get('Type') == 'Address' ]
JSON = {'Items' : new_items }
for only heighlight data
new_items = [ j.get('heighlight') for j in JSON['Items'] if j.get('Type') == 'Address' ]
To obtain a list of highlights objects with Address Type
[highlight for highlight in respose['Items'] if highlight['Type'] == 'Address']

Logic for building converter using python dictionary values

I have such slice of loaded json tp python dictionary (size_dict):
{
"sizeOptionName":"XS",
"sizeOptionId":"1528",
"sortOrderNumber":"7017"
},
{
"sizeOptionName":"S",
"sizeOptionId":"1529",
"sortOrderNumber":"7047"
},
{
"sizeOptionName":"M",
"sizeOptionId":"1530",
"sortOrderNumber":"7095"
}
and I have products with size Id (dictionary_prod):
{
"catalogItemId":"7627712",
"catalogItemTypeId":"3",
"regularPrice":"0.0",
"sizeDimension1Id":"1528",
"sizeDimension2Id":"0",
}
I need to make such as output for any product:
result_dict = {'variant':
[{"catalogItemId":"7627712", ...some other info...,
'sizeName': 'XS', 'sizeId': '1525'}}]}
so I need to convert size ID and add it to new result object
What is the best pythonic way to do this?
I dont know how to get right data from size_dict
if int(dictionary_prod['sizeDimension1Id']) > o:
(result_dict['variant']).append('sizeName': size_dict???)
As Tommy mentioned, this is best facilitated by mapping the size id's to their respective dictionaries.
size_dict = \
[
{
"sizeOptionName":"XS",
"sizeOptionId":"1528",
"sortOrderNumber":"7017"
},
{
"sizeOptionName":"S",
"sizeOptionId":"1529",
"sortOrderNumber":"7047"
},
{
"sizeOptionName":"M",
"sizeOptionId":"1530",
"sortOrderNumber":"7095"
}
]
size_id_map = {size["sizeOptionId"] : size for size in size_dict}
production_dict = \
[
{
"catalogItemId":"7627712",
"catalogItemTypeId":"3",
"regularPrice":"0.0",
"sizeDimension1Id":"1528",
"sizeDimension2Id":"0",
}
]
def make_variant(idict):
odict = idict.copy()
size_id = odict.pop("sizeDimension1Id")
odict.pop("sizeDimension2Id")
odict["sizeName"] = size_id_map[size_id]["sizeOptionName"]
odict["sizeId"] = size_id
return odict
result_dict = \
{
"variant" : [make_variant(product) for product in production_dict]
}
print(result_dict)
Your question is a little confusing but it looks like you have a list (size_dict) of dictionaries that contain some infroamtion and you want to do a lookup to find a particular element in the list that contains the SizeOptionName you are interested in so that you can read off the SizeOptionID.
So first you could organsie your size_dict as a dictionary rather than a list - i.e.
sizeDict = {"XS":{
"sizeOptionName":"XS",
"sizeOptionId":"1528",
"sortOrderNumber":"7017"
}, "S": {
"sizeOptionName":"S",
"sizeOptionId":"1529",
"sortOrderNumber":"7047"
}, ...
You could then read off the SizeOptionID you need by doing:
sizeDict[sizeNameYouAreLookingFor][SizeOptionID]
Alternative you could keep your current structure and just search the list of dictionaries that is size_dict.
So:
for elem in size_dict:
if elem.SizeOptionID == sizeYouAreLookingFor:
OptionID = elem.SizeOptionId
Or perhaps you are asking something else?

Categories