I have this sample JSON which is complex and has many levels of nesting as well items in in:
{
"resourceType": "Single",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid",
"resource": {
"resourceType": "Employee",
"id": "4cb1a87c",
"text": {
"status": "generated",
"div": "generated"
},
"extension": [],
"identifier": [
{
"system": "https://github.com",
"value": "43f123441901"
}
],
"name": [
{
"use": "official",
"family": "Shields52",
"given": [
"Aaro97"
],
"prefix": [
"Mr."
]
}
],
"maritalStatus": {
"coding": [
{
"system": "MaritalStatus",
"code": "M",
"display": "M"
}
],
"text": "M"
},
"multipleBirthBoolean": false
},
"request": {
"method": "POST",
"url": "User"
}
},
{
"fullUrl": "f411764e1f01",
"resource": {
"resourceType": "Claim",
"id": "411764e1f01",
"status": "active",
"type": {
"coding": [
{
"system": "type",
"code": "Company"
}
]
},
"use": "claim",
"employee": {
"reference": "1141dfb308"
},
"billablePeriod": {
"start": "2009-12-24T16:42:36-05:00",
"end": "2009-12-24T16:57:36-05:00"
},
"created": "2009-12-24T16:57:36-05:00",
"provider": {
"reference": "7e31e2b3feb"
},
"priority": {
"coding": [
{
"system": "Employee",
"code": "normal"
}
]
},
"procedure": [
{
"sequence": 1,
"procedureReference": {
"reference": "58f373a0a0e"
}
}
],
"insurance": [
{
"sequence": 1,
"focal": true,
"coverage": {
"display": "Employer"
}
}
],
"item": [
{
"sequence": 1,
"productOrService": {
"coding": [
{
"system": "http://comp1.info/",
"code": "1349003",
"display": "check up"
}
],
"text": "check up"
},
"encounter": [
{
"reference": "bc0a5705f6"
}
]
},
{
"sequence": 2,
"procedureSequence": [
1
],
"productOrService": {
"coding": [
{
"system": "http://comp.info",
"code": "421000124101",
"display": "Documentation"
}
],
"text": "Documentation"
},
"net": {
"value": 116.60,
"currency": "USD"
}
}
],
"total": {
"value": 163.7,
"currency": "USD"
}
},
"request": {
"method": "POST",
"url": "Employee"
}
}
]
}
I have only kept 2 items under entry
but in actual there are thousands of items.
What I am trying to do is find, print all occurrences of a key (print and save key and value both of each occurrence) into a separate dict. So, for example if in above case, I want to find all data for key ‘productOrService’, then print
"productOrService": {
"coding": [
{
"system": "http://comp.info",
"code": "421000124101",
"display": "Documentation"
}
],
"text": "Documentation"
}
Similarly I have to search for any other key at any level of nesting – for example search for insurance
.
Here is the code I have:
def findkeys(node, kv):
if isinstance(node, list):
for i in node:
for x in findkeys(i, kv):
print(x)
elif isinstance(node, dict):
if kv in node:
yield node[kv]
for j in node.values():
for x in findkeys(j, kv):
print(x)
When I execute about with findkeys(input_json,'productOrService')
, then I don’t see any output coming in. Not sure what mistake I am making
Edit: I understand the issue is with use yield
but I can’t figure out how to replace yield
2
Answers
You are using
yield
in your function, that means that it is not a function anymore – it’s a iterator. If you want to get an output, iterate through it:for x in findkeys(node,"productOrService"): print(x)
Your function returns a generator, which is not printed. Try
list(findkeys(input_json,'productOrService'))
, which will print to the console.If you don’t want to use
yield
, you can instead just iterate over the JSON data recursively and print whenever you encounter a match, without iterating over the output of your functionfindkeys
. So you can try something like this: