I have a json file that looks something like the following:
[
{
"category1":"0120391123123"
},
[
{
"subcategory":"0120391123123"
},
[
{
"subsubcategory":"019301948109"
},
[
{
"subsubsubcategory":"013904123908"
},
[
{
"subsubsubsubcategory":"019341823908"
}
]
]
]
],
[
{
"subcategory2":"0934810923801"
},
[
{
"subsubcategory2":"09341829308123"
}
]
],
[
{
"category2":"1309183912309"
},
[
{
"subcategory":"10293182094"
}
]
]
]
I also have a list of categories that I would like to find in the original list. If the category exists in categoriesToFind, I would also like to find all subcategories and return those as well.
categoriesToFind = ['019301948109', '1309183912309']
finalCategories = []
def findCategories(currentList, isFirstIteration):
for x in currentList:
if type(x) is dict and (next(iter(x.values())) in categoriesToFind or not isFirstIteration):
finalCategories.append(next(iter(x.values())))
if len(currentList) < currentList.index(x) + 1:
findCategories(currentList[currentList.index(x) + 1], False)
findCategories(data, True)
I would want finalCategories to contain the following:
['019301948109', '013904123908', '019341823908', '1309183912309', '10293182094']
You can use recursion with a generator:
categoriesToFind = ['019301948109', '1309183912309']
d = [{'category1': '0120391123123'}, [{'subcategory': '0120391123123'}, [{'subsubcategory': '019301948109'}, [{'subsubsubcategory': '013904123908'}, [{'subsubsubsubcategory': '019341823908'}]]]], [{'subcategory2': '0934810923801'}, [{'subsubcategory2': '09341829308123'}]], [{'category2': '1309183912309'}, [{'subcategory': '10293182094'}]]]
def get_subcategories(_d, _flag):
flag = None
for i in _d:
if isinstance(i, dict):
_val = list(i.values())[0]
if _val in categoriesToFind or _flag:
yield _val
flag = True
else:
yield from get_subcategories(i, _flag or flag)
print(list(get_subcategories(d, False)))
Output:
['019301948109', '013904123908', '019341823908', '1309183912309', '10293182094']
Related
I am trying to create a complex object based on metadata I have. It is an array of attributes which I am iterating and trying to create a dict. For example below is the array:
[
"itemUniqueId",
"itemDescription",
"manufacturerInfo[0].manufacturer.value",
"manufacturerInfo[0].manufacturerPartNumber",
"attributes.noun.value",
"attributes.modifier.value",
"attributes.entityAttributes[0].attributeName",
"attributes.entityAttributes[0].attributeValue",
"attributes.entityAttributes[0].attributeUOM",
"attributes.entityAttributes[1].attributeName",
"attributes.entityAttributes[1].attributeValue",
"attributes.entityAttributes[1].attributeUOM",
]
This array should give an output as below:
{
"itemUniqueId": "",
"itemDescription": "",
"manufacturerInfo": [
{
"manufacturer": {
"value": ""
},
"manufacturerPartNumber": ""
}
],
"attributes": {
"noun": {
"value": ""
},
"modifier": {
"value": ""
},
"entityAttributes": [
{
"attributeName": "",
"attributeValue": "",
"attributeUOM": ""
},
{
"attributeName": "",
"attributeValue": "",
"attributeUOM": ""
}
]
}
}
I have written this logic but unable to get the desired output. It should work on both object and array given the metadata.
source_json = [
"itemUniqueId",
"itemDescription",
"manufacturerInfo[0].manufacturer.value",
"manufacturerInfo[0].manufacturerPartNumber",
"attributes.noun.value",
"attributes.modifier.value",
"attributes.entityAttributes[0].attributeName",
"attributes.entityAttributes[0].attributeValue",
"attributes.entityAttributes[0].attributeUOM",
"attributes.entityAttributes[1].attributeName",
"attributes.entityAttributes[1].attributeValue",
"attributes.entityAttributes[1].attributeUOM",
]
for row in source_json:
propertyNames = row.split('.')
temp = ''
parent = {}
parentArr = []
parentObj = {}
# if len(propertyNames) > 1:
arrLength = len(propertyNames)
for i, (current) in enumerate(zip(propertyNames)):
if i == 0:
if '[' in current:
parent[current]=parentArr
else:
parent[current] = parentObj
temp = current
if i > 0 and i < arrLength - 1:
if '[' in current:
parent[current] = parentArr
else:
parent[current] = parentObj
temp = current
if i == arrLength - 1:
if '[' in current:
parent[current] = parentArr
else:
parent[current] = parentObj
temp = current
# temp[prev][current] = ""
# finalMapping[target] = target
print(parent)
There's a similar question at Convert Dot notation string into nested Python object with Dictionaries and arrays where the accepted answer works for this question, but has unused code paths (e.g. isInArray) and caters to unconventional conversions expected by that question:
❓ "arrOne[0]": "1,2,3" → "arrOne": ["1", "2", "3"] instead of
✅ "arrOne[0]": "1,2,3" → "arrOne": ["1,2,3"] or
✅ "arrOne[0]": "1", "arrOne[1]": "2", "arrOne[2]": "3" → "arrOne": ["1", "2", "3"]
Here's a refined implementation of the branch function:
def branch(tree, path, value):
key = path[0]
array_index_match = re.search(r'\[([0-9]+)\]', key)
if array_index_match:
# Get the array index, and remove the match from the key
array_index = int(array_index_match[0].replace('[', '').replace(']', ''))
key = key.replace(array_index_match[0], '')
# Prepare the array at the key
if key not in tree:
tree[key] = []
# Prepare the object at the array index
if array_index == len(tree[key]):
tree[key].append({})
# Replace the object at the array index
tree[key][array_index] = value if len(path) == 1 else branch(tree[key][array_index], path[1:], value)
else:
# Prepare the object at the key
if key not in tree:
tree[key] = {}
# Replace the object at the key
tree[key] = value if len(path) == 1 else branch(tree[key], path[1:], value)
return tree
Usage:
VALUE = ''
def create_dict(attributes):
d = {}
for path_str in attributes:
branch(d, path_str.split('.'), VALUE)
return d
source_json = [
"itemUniqueId",
"itemDescription",
"manufacturerInfo[0].manufacturer.value",
"manufacturerInfo[0].manufacturerPartNumber",
"attributes.noun.value",
"attributes.modifier.value",
"attributes.entityAttributes[0].attributeName",
"attributes.entityAttributes[0].attributeValue",
"attributes.entityAttributes[0].attributeUOM",
"attributes.entityAttributes[1].attributeName",
"attributes.entityAttributes[1].attributeValue",
"attributes.entityAttributes[1].attributeUOM",
]
assert create_dict(source_json) == {
"itemUniqueId": "",
"itemDescription": "",
"manufacturerInfo": [
{
"manufacturer": {
"value": ""
},
"manufacturerPartNumber": ""
}
],
"attributes": {
"noun": {
"value": ""
},
"modifier": {
"value": ""
},
"entityAttributes": [
{
"attributeName": "",
"attributeValue": "",
"attributeUOM": ""
},
{
"attributeName": "",
"attributeValue": "",
"attributeUOM": ""
}
]
}
}
First we should iterate over whole list and store each 3rd attributes, after that we could change this struct to our desired output:
from typing import Dict, List
source_json = [
"attributes.entityAttributes[0].attributeName",
"attributes.entityAttributes[0].attributeValue",
"attributes.entityAttributes[0].attributeUOM",
"attributes.entityAttributes[1].attributeName",
"attributes.entityAttributes[1].attributeValue",
"attributes.entityAttributes[1].attributeUOM",
"attributes.entityAttributes[2].attributeName"
]
def accumulate(source: List) -> Dict:
accumulator = {}
for v in source:
vs = v.split(".")
root_attribute = vs[0]
if not root_attribute in accumulator:
accumulator[root_attribute] = {}
i = vs[1].rfind('[')
k = (vs[1][:i], vs[1][i+1:-1])
if not k in accumulator[root_attribute]:
accumulator[root_attribute][k] = {}
accumulator[root_attribute][k][vs[2]] = ""
return accumulator
def get_result(accumulated: Dict) -> Dict:
result = {}
for k, v in accumulated.items():
result[k] = {}
for (entity, idx), v1 in v.items():
if not entity in result[k]:
result[k][entity] = []
if len(v1) == 3:
result[k][entity].append(v1)
return result
print(get_result(accumulate(source_json)))
The output will be:
{
'attributes':
{
'entityAttributes':
[
{
'attributeName': '',
'attributeValue': '',
'attributeUOM': ''
},
{'attributeName': '',
'attributeValue': '',
'attributeUOM': ''
}
]
}
}
In accumulate function we store 3rd level attributes in Dict with (entityAttributes, 0) ... (entityAttributes, 2) keys.
In get_result function we convert Dict with (entityAttributes, 0) ... (entityAttributes, 2) keys to Dict from string to List.
How about something like this:
import re
import json
source_json = [
"attributes.entityAttributes[0].attributeName",
"attributes.entityAttributes[0].attributeValue",
"attributes.entityAttributes[0].attributeUOM",
"attributes.entityAttributes[1].attributeName",
"attributes.entityAttributes[1].attributeValue",
"attributes.entityAttributes[1].attributeUOM",
"attributes.entityAttributes[2].attributeName"
]
def to_object(source_json):
def add_attribute(target, attribute_list):
head, tail = attribute_list[0], attribute_list[1:]
if tail:
add_attribute(target.setdefault(head,{}), tail)
else:
target[head] = ''
target = {}
for row in source_json:
add_attribute(target, re.split(r'[\.\[\]]+',row))
return target
print(json.dumps(to_object(source_json), indent=4))
Note that this will not exactly do what you requested. It interprets stores the array also as an object with keys '0' ... '2'. This makes it easier to implement and also more stable. What would you expect, when the input list missed the entries with entityAttributes[0]. Should the list include an empty element or something different. Anyway you save space by not including this element, which works only if you store the array in an object.
None of the answers provided so far strike me as very intuitive. Here's one way
to tackle the problem with three easy-to-understand functions.
Normalize inputs. First we need a function to normalize the inputs strings. Instead of rules-bearing strings like
'foo[0].bar' – where one must understand that integers
in square brackets imply a list – we want a simple tuple
of keys like ('foo', 0, 'bar').
def attribute_to_keys(a):
return tuple(
int(k) if k.isdigit() else k
for k in a.replace('[', '.').replace(']', '').split('.')
)
Build a uniform data structure. Second, we need a function to assemble a data structure consisting of dicts
of dicts of dicts ... all the way down.
def assemble_data(attributes):
data = {}
for a in attributes:
d = data
for k in attribute_to_keys(a):
d = d.setdefault(k, {})
return convert(data)
def convert(d):
# Just a placeholder for now.
return d
Convert the uniform data. Third, we need to implement a real version of the placeholder. Specifically, we
need it to recursively convert the uniform data structure into our ultimate
goal having (a) empty strings at leaf nodes, and (b) lists rather than dicts
whenever the dict keys are all integers. Note that this even fills in empty
list positions with an empty string (a contingency not covered in your problem
description; adjust as needed if you want a different behavior).
def convert(d):
if not d:
return ''
elif all(isinstance(k, int) for k in d):
return [convert(d.get(i)) for i in range(max(d) + 1)]
else:
return {k : convert(v) for k, v in d.items()}
You can use a custom builder class which implements __getattr__ and __getitem__ to gradually build the underlying object. This building can then be triggered by using eval on each of the attribute strings (note: eval is not safe for input from untrusted sources).
The following is an example implementation:
class Builder:
def __init__(self):
self.obj = None
def __getattr__(self, key):
if self.obj is None:
self.obj = {}
return self.obj.setdefault(key, Builder())
def __getitem__(self, index):
if self.obj is None:
self.obj = []
self.obj.extend(Builder() for _ in range(index+1-len(self.obj)))
return self.obj[index]
def convert(self):
if self.obj is None:
return ''
elif isinstance(self.obj, list):
return [v.convert() for v in self.obj]
elif isinstance(self.obj, dict):
return {k: v.convert() for k,v in self.obj.items()}
else:
assert False
attributes = [
'itemUniqueId',
'itemDescription',
'manufacturerInfo[0].manufacturer.value',
'manufacturerInfo[0].manufacturerPartNumber',
'attributes.noun.value',
'attributes.modifier.value',
'attributes.entityAttributes[0].attributeName',
'attributes.entityAttributes[0].attributeValue',
'attributes.entityAttributes[0].attributeUOM',
'attributes.entityAttributes[1].attributeName',
'attributes.entityAttributes[1].attributeValue',
'attributes.entityAttributes[1].attributeUOM',
]
builder = Builder()
for attr in attributes:
eval(f'builder.{attr}')
result = builder.convert()
import json
print(json.dumps(result, indent=4))
which gives the following output:
{
"itemUniqueId": "",
"itemDescription": "",
"manufacturerInfo": [
{
"manufacturer": {
"value": ""
},
"manufacturerPartNumber": ""
}
],
"attributes": {
"noun": {
"value": ""
},
"modifier": {
"value": ""
},
"entityAttributes": [
{
"attributeName": "",
"attributeValue": "",
"attributeUOM": ""
},
{
"attributeName": "",
"attributeValue": "",
"attributeUOM": ""
}
]
}
}
I'm trying to print all values from a JSON file but it only prints the last one.
example Json file:
[
{
"folderTeste9": [
{
"_aliasinput": "folderTeste9",
"_idinput": "folderteste132131",
"_timesinput": [
"10:20"
],
"_statusinput": "true"
}
]
},
{
"testeFolder1991": [
{
"_aliasinput": "testeFolder1991",
"_idinput": "testefolder1991",
"_timesinput": [],
"_statusinput": "true"
}
]
},
{
"Flo.": [
{
"_aliasinput": "Flo.",
"_idinput": "12321354564613",
"_timesinput": [],
"_statusinput": "true"
}
]
}
]
My Code
import json
with open('config/'+'config.json', 'r') as file:
data: list = json.load(file)
lista = data
for element in lista:
print("")
for alias_element in element:
#print("Alias: " +alias_element)
for result in element[alias_element]:
profile_data = result
aliasInput = profile_data['_aliasinput']
timesInput = profile_data['_timesinput']
idInput = profile_data['_idinput']
statusInput = profile_data['_statusinput']
print(f" Values from register are {aliasInput}{timesInput}{idInput}{statusInput}")
Actual Result
Values from register are Flo. [] 12321354564613 true
Expected Result
I'd like to print all values from the different register.
Example:
Values from register are folderTest9 [10:20] folderteste132131 true
[...]
Values from register are Flo. [] 12321354564613 true
I know that there are a lot of questions about duplicates but I can't find a solution suitable for me.
I have a json structure like this:
{
"test": [
{
"name2": [
"Tik",
"eev",
"asdv",
"asdfa",
"sadf",
"Nick"
]
},
{
"name2": [
"Tik",
"eev",
"123",
"r45",
"676",
"121"
]
}
]
}
I want to keep the first value and remove all the other duplicates.
Expected Result
{
"test": [
{
"name2": [
"Tik",
"eev",
"asdv",
"asdfa",
"sadf",
"Nick"
]
},
{
"name2": [
"123",
"r45",
"676",
"121"
]
}
]
}
I tried using a tmp to check for duplicates but it didn't seem to work. Also I can't find a way to make it json again.
import json
with open('myjson') as access_json:
read_data = json.load(access_json)
tmp = []
tmp2 = []
def get_synonyms():
ingredients_access = read_data['test']
for x in ingredients_access:
for j in x['name2']:
tmp.append(j)
if j in tmp:
tmp2.append(j)
get_synonyms()
print(len(tmp))
print(len(tmp2))
You can use recursion:
def filter_d(d):
seen = set()
def inner(_d):
if isinstance(_d, dict):
return {a:inner(b) if isinstance(b, (dict, list)) else b for a, b in _d.items()}
_r = []
for i in _d:
if isinstance(i, (dict, list)):
_r.append(inner(i))
elif i not in seen:
_r.append(i)
seen.add(i)
return _r
return inner(d)
import json
print(json.dumps(filter_d(data), indent=4))
Output:
{
"test": [
{
"name2": [
"Tik",
"eev",
"asdv",
"asdfa",
"sadf",
"Nick"
]
},
{
"name2": [
"123",
"r45",
"676",
"121"
]
}
]
}
You are first adding everything to tmp and then to tmp2 because every value was added to tmp before.
I changed the function a little bit to work for your specific test example:
def get_synonyms():
test_list = []
ingredients_access = read_data['test']
used_values =[]
for x in ingredients_access:
inner_tmp = []
for j in x['name2']:
if j not in used_values:
inner_tmp.append(j)
used_values.append(j)
test_list.append({'name2':inner_tmp})
return {'test': test_list}
result = get_synonyms()
print(result)
Output:
{'test': [{'name2': ['Tik', 'eev', 'asdv', 'asdfa', 'sadf', 'Nick']}, {'name2': ['123', 'r45', '676', '121']}]}
Here's a little hackish answer:
d = {'test': [{'name2': ['Tik', 'eev', 'asdv', 'asdfa', 'sadf', 'Nick']},
{'name2': ['Tik', 'eev', '123', 'r45', '676', '121']}]}
s = set()
for l in d['test']:
l['name2'] = [(v, s.add(v))[0] for v in l['name2'] if v not in s]
Output:
{'test': [{'name2': ['Tik', 'eev', 'asdv', 'asdfa', 'sadf', 'Nick']},
{'name2': ['123', 'r45', '676', '121']}]}
This uses a set to track the unique values, and add unique values to set while returning the value back to the list.
I have a text file that is formatted like the following, with each hyphen representing a hierarchy for the list item.
category1 : 0120391123123
- subcategory : 0120391123123
-- subsubcategory : 019301948109
--- subsubsubcategory : 013904123908
---- subsubsubsubcategory : 019341823908
- subcategory2 : 0934810923801
-- subsubcategory2 : 09341829308123
category2: 1309183912309
- subcategory : 10293182094
...
How can I programmatically get a list like this into a json format like the following?
[
{
"category1":"0120391123123"
},
[
{
"subcategory":"0120391123123"
},
[
{
"subsubcategory":"019301948109"
},
[
{
"subsubsubcategory":"013904123908"
},
[
{
"subsubsubsubcategory":"019341823908"
}
]
]
]
],
[
{
"subcategory2":"0934810923801"
},
[
{
"subsubcategory2":"09341829308123"
}
]
],
[
{
"category2":"1309183912309"
},
[
{
"subcategory":"10293182094"
}
]
]
]
use a recursive function to split the content of the file to chunks and use divide and conquer
from pprint import pprint
req=[]
startingindex=-1
with open('temp.txt' ,'r') as f:
content=f.read().split('\n')
def foo(splitcontent):
index=0
reqlist=[]
while(index<len(splitcontent)):
if (splitcontent[index][0]!='-'):
key,value=splitcontent[index].split(':')
reqlist.append({key.strip():value.strip()})
index+=1
templist=[]
while(index<len(splitcontent) and splitcontent[index][0]=='-'):
templist.append(splitcontent[index][1:])
index+=1
intermediatelist=foo(templist)
if(intermediatelist):
reqlist.append(intermediatelist)
return reqlist
pprint(foo(content))
OUTPUT
[{'category1': '0120391123123'},
[{'subcategory': '0120391123123'},
[{'subsubcategory': '019301948109'},
[{'subsubsubcategory': '013904123908'},
[{'subsubsubsubcategory': '019341823908'}]]],
{'subcategory2': '0934810923801'},
[{'subsubcategory2': '09341829308123'}]],
{'category2': '1309183912309'},
[{'subcategory': '10293182094'}]]
You can use recursion with itertools.groupby:
s = """
category1 : 0120391123123
- subcategory : 0120391123123
-- subsubcategory : 019301948109
--- subsubsubcategory : 013904123908
---- subsubsubsubcategory : 019341823908
- subcategory2 : 0934810923801
-- subsubcategory2 : 09341829308123
category2: 1309183912309
- subcategory : 10293182094
"""
import re, itertools
data = list(filter(None, s.split('\n')))
def group_data(d):
if len(d) == 1:
return [dict([re.split('\s*:\s*', d[0])])]
grouped = [[a, list(b)] for a, b in itertools.groupby(d, key=lambda x:not x.startswith('-'))]
_group = [[grouped[i][-1], grouped[i+1][-1]] for i in range(0, len(grouped), 2)]
_c = [[dict([re.split('\s*:\s*', i) for i in a]), group_data([c[1:] for c in b])] for a, b in _group]
return [i for b in _c for i in b]
print(json.dumps(group_data(data), indent=4))
Output:
[
{
"category1": "0120391123123"
},
[
{
" subcategory": "0120391123123"
},
[
{
" subsubcategory": "019301948109"
},
[
{
" subsubsubcategory": "013904123908"
},
[
{
" subsubsubsubcategory": "019341823908"
}
]
]
],
{
" subcategory2": "0934810923801"
},
[
{
" subsubcategory2": "09341829308123"
}
]
],
{
"category2": "1309183912309"
},
[
{
" subcategory": "10293182094"
}
]
]
Note: this answer assumes that your final output should have "category2" be at the same level as "category1", since both do not contain a "-" in the front.
I am trying to play with an open fda API. So far everything works well. Issue is coming for nested JSON data.
Here is my Json data:
{
"seriousnessother": "1",
"reportduplicate": {
"duplicatenumb": "US-BRISTOL-MYERS SQUIBB COMPANY-BMS-2017-086135",
"duplicatesource": "BRISTOL MYERS SQUIBB"
},
"safetyreportversion": "1",
"receiptdate": "20170927",
"duplicate": "1",
"seriousnessdeath": "1",
"receivedate": "20170927",
"patient": {
"reaction": [
{
"reactionmeddrapt": "Death",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "5"
},
{
"reactionmeddrapt": "Product use in unapproved indication",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "6"
}
],
"patientsex": "1",
"drug": [
{
"drugstartdateformat": "102",
"medicinalproduct": "OPDIVO",
"drugindication": "COLORECTAL CANCER",
"drugcharacterization": "1",
"drugadministrationroute": "065",
"drugenddateformat": "102",
"drugseparatedosagenumb": "1",
"drugstructuredosageunit": "032",
"openfda": {
"manufacturer_name": [
"E.R. Squibb & Sons, L.L.C."
],
"unii": [
"31YO63LBSN"
],
"product_type": [
"HUMAN PRESCRIPTION DRUG"
],
"spl_set_id": [
"f570b9c4-6846-4de2-abfa-4d0a4ae4e394"
],
"route": [
"INTRAVENOUS"
],
"generic_name": [
"NIVOLUMAB"
],
"brand_name": [
"OPDIVO"
],
"product_ndc": [
"0003-3772",
"0003-3734",
"0003-3774"
],
"pharm_class_epc": [
"Programmed Death Receptor-1 Blocking Antibody [EPC]"
],
"substance_name": [
"NIVOLUMAB"
],
"spl_id": [
"2d33126d-5115-459e-bcaf-d0ace4fbe94e"
],
"pharm_class_moa": [
"Programmed Death Receptor-1-directed Antibody Interactions [MoA]"
],
"application_number": [
"BLA125554"
],
"nui": [
"N0000191259",
"N0000191260"
],
"package_ndc": [
"0003-3734-13",
"0003-3772-11",
"0003-3774-12"
]
},
"drugstructuredosagenumb": "1",
"drugintervaldosageunitnumb": "2",
"drugstartdate": "20160907",
"actiondrug": "5",
"activesubstance": {
"activesubstancename": "NIVOLUMAB"
},
"drugintervaldosagedefinition": "803",
"drugauthorizationnumb": "125554",
"drugrecurreadministration": "3",
"drugdosagetext": "1 DF, Q2WK",
"drugenddate": "20161222",
"drugadditional": "3"
}
]
},
"occurcountry": "US",
"reporttype": "1",
"companynumb": "US-BRISTOL-MYERS SQUIBB COMPANY-BMS-2017-086135",
"safetyreportid": "14015990",
"sender": {
"senderorganization": "FDA-Public Use",
"sendertype": "2"
},
"transmissiondate": "20171128",
"fulfillexpeditecriteria": "1",
"transmissiondateformat": "102",
"receiptdateformat": "102",
"receiver": {
"receiverorganization": "FDA",
"receivertype": "6"
},
"serious": "1",
"receivedateformat": "102",
"primarysource": {
"reportercountry": "US",
"qualification": "5"
},
"primarysourcecountry": "US"
}
Here is my view to call this data and convert to Django data.
json_data = open('/users/downloads/drug-bad.json').read()
response = json.loads(json_data)
a=0
b=0
for data in response['results']:
#try:
seriousnessother = data.get('seriousnessother')
reportduplicate_duplicatenumb = data['reportduplicate'].get('duplicatenumb')
reportduplicate_duplicatesource = data['reportduplicate'].get('duplicatesource')
safetyreportversion = data.get('safetyreportversion')
receiptdate = data.get('receiptdate')
duplicate = data.get('duplicate')
seriousnessdeath = data.get('seriousnessdeath')
receivedate = data.get('receivedate')
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
patient_reaction_reactionmeddraversionpt = data['patient']['reaction'].get('reactionmeddraversionpt')
patient_reaction_reactionoutcome = data['patient']['reaction'].get('reactionoutcome')
patient_patientsex = data['patient'].get('patientsex')
patient_drug_medicinalproduct = data['patient']['drug'].get('medicinalproduct')
patient_drug_drugindication = data['patient']['drug'].get('drugindication')
patient_drug_drugcharacterization = data['patient']['drug'].get('drugcharacterization')
patient_drug_drugadministrationroute = data['patient']['drug'].get('drugadministrationroute')
patient_drug_drugseparatedosagenumb = data['patient']['drug'].get('drugseparatedosagenumb')
patient_drug_drugstructuredosageunit = data['patient']['drug'].get('drugstructuredosageunit')
patient_drug_openfda_manufacturer_name = data['patient']['drug']['openfda']['manufacturer'].get('name')
patient_drug_openfda_unii = data['patient']['drug']['openfda'].get('unii')
patient_drug_openfda_product_type = data['patient']['drug']['openfda']['product'].get('type')
patient_drug_openfda_spl_set_id = data['patient']['drug']['openfda']['spl']['set'].get('id')
patient_drug_openfda_route = data['patient']['drug']['openfda'].get('route')
patient_drug_openfda_generic_name = data['patient']['drug']['openfda']['generic'].get('name')
patient_drug_openfda_brand_name = data['patient']['drug']['openfda']['brand'].get('name')
patient_drug_openfda_product_ndc = data['patient']['drug']['openfda']['product'].get('ndc')
patient_drug_openfda_pharm_class_epc = data['patient']['drug']['openfda']['pharm']['class'].get('epc')
patient_drug_openfda_substance_name = data['patient']['drug']['openfda']['substance'].get('name')
patient_drug_openfda_spl_id = data['patient']['drug']['openfda']['spl'].get('id')
patient_drug_openfda_pharm_class_moa = data['patient']['drug']['openfda']['pharm']['class'].get('moa')
patient_drug_openfda_application_number = data['patient']['drug']['openfda']['application'].get('number')
patient_drug_openfda_nui = data['patient']['drug']['openfda'].get('nui')
patient_drug_openfda_package_ndc = data['patient']['drug']['openfda']['package'].get('ndc')
patient_drug_drugstructuredosagenumb = data['patient']['drug'].get('drugstructuredosagenumb')
patient_drug_drugintervaldosageunitnumb = data['patient']['drug'].get('drugintervaldosageunitnumb')
patient_drug_drugstartdate = data['patient']['drug'].get('drugstartdate')
patient_drug_actiondrug = data['patient']['drug'].get('actiondrug')
patient_drug_activesubstance_activesubstancename = data['patient']['drug']['activesubstance'].get('activesubstancename')
patient_drug_drugintervaldosagedefinition = data['patient']['drug'].get('drugintervaldosagedefinition')
patient_drug_drugauthorizationnumb = data['patient']['drug'].get('drugauthorizationnumb')
patient_drug_drugrecurreadministration = data['patient']['drug'].get('drugrecurreadministration')
patient_drug_drugdosagetext = data['patient']['drug'].get('drugdosagetext')
patient_drug_drugenddate = data['patient']['drug'].get('drugenddate')
patient_drug_drugadditional = data['patient']['drug'].get('drugadditional')
occurcountry = data.get('occurcountry')
reporttype = data.get('reporttype')
companynumb = data.get('companynumb')
safetyreportid = data.get('safetyreportid')
sender_senderorganization = data['sender'].get('senderorganization')
sender_sendertype = data['sender'].get('sendertype')
fulfillexpeditecriteria = data.get('fulfillexpeditecriteria')
receiver_receiverorganization = data['receiver'].get('receiverorganization')
receiver_receivertype = data['receiver'].get('receivertype')
serious = data.get('serious')
primarysource_reportercountry = data['primarysource'].get('reportercountry')
primarysource_qualification = data['primarysource'].get('qualification')
primarysourcecountry = data.get('primarysourcecountry')
I am getting following error:
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
AttributeError: 'list' object has no attribute 'get'
Note that there are many data in response result. It could be that one of result does not have patient field. But as get method should return None if it does not exist.
I want either the field value or None.
It works for simple Json data but error comes when there are array/list inside array/list.
Since reaction is list you should do something like this:
reactions = data['patient']['reaction']
if reactions and isinstance(reactions, list):
for reaction in reactions:
patient_reaction_reactionmeddrapt = reaction.get('reactionmeddrapt')
else:
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
instead of simple:
patient_reaction_reactionmeddrapt = data['patient']['reaction'].get('reactionmeddrapt')
data['patient']['reaction'] in your code return list objects. So you need to iterate over it to get reactionmeddrapt for each list element.
Given your input json:
"patient": {
"reaction": [
{
"reactionmeddrapt": "Death",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "5"
},
{
"reactionmeddrapt": "Product use in unapproved indication",
"reactionmeddraversionpt": "20.1",
"reactionoutcome": "6"
}
],
The data value for "reactions" is a list. Also as I understand it, you want to get the "reactionmeddrapt" attribute value or None if you don't have a data value for "patient".
You could do something like this:
try:
reactions = data['patient']['reaction']
except KeyError:
return None
if reactions and isinstance(reactions, list):
# Assuming you want to iterate over the list
for reaction in reactions:
reactionmeddrapt = reaction.get('reactionmeddrapt')