Getting Keyerror when accessing an element in JSON, python - python

I've seen this asked a multitude of times, but I think the JSON I'm looking to access is a bit different. I'm looking at a JSON with this format:
{
"timestamp": 1589135576,
"level": 20,
"gender": "Male",
"status": {},
"personalstats": {},
"attacks": {
"103307874": {
"code": "cc7bc5ab6fbd54f49a2e879c49e70183",
"result": "Mugged",
"chain": 2,
"modifiers": {
"fairFight": 3,
"war": 1,
}
},
"103320473": {
"code": "3184c1e2c9662fd70a21f03a637cb02e",
"result": "Mugged",
"chain": 1,
"modifiers": {
"fairFight": 1.07,
"war": 1,
}
},
}
}
There are 98 more "attack" below the first two here.
Now I thought I could access the first attacks result with this code, but it results in a key error. Anyone understand why?
currentresponse = requests.get("URL")
json_obj = json.loads(currentresponse.text)
lastresult = json_obj["attacks"][0]["result"]
As a "bonus" I can access the result of the attack through the following code.
json_obj["attacks"]["103320473"]["result"]

Yeah, you can't access with json_obj["attacks"][0], because it's not a list, and hence doesn't have indexing like a list. These are nested dicts, so you have to access them by dict rules (access by key)

Related

Only getting string while iterating through json data

JSON:
{
"status": "success",
"data": {
"9": {
"1695056": {
"id": "1695056",
[...]
},
"csevents": {
"2807": {
"id": "2807",
"startdate": "2019-01-24 18:45:00",
"service_texts": [],
"eventTemplate": "1"
},
"2810": {
"id": "2810",
"startdate": "2019-01-31 18:45:00",
"service_texts": [],
"eventTemplate": "1"
}
}
},
"1695309": {
"id": "1695309",
[...]
},
"csevents": {
"3601": {
"id": "3601",
"startdate": "2019-05-17 18:45:00",
"service_texts": [],
"eventTemplate": "1"
}
I try to get the members from "csevents" ("2807", "2810", 3601") with python. Problem is that i don't know the IDs in "9" ("1695056", "1695309") while coding.
So i tried to iterate through "9" and then through "csevents" but if i iterate through "9" i only get a string so i can't iterate through "csevents" anymore.
Python:
for whatever in json_object['data']['9']:
for id in whatever['csevents']:
print(id)
So that doesn't work. Does anybody know how I can solve that?
Thanks
Had to clean up your JSON string to get it to work, but looking at your solution is seems like you're iterating directly from your dict, what you should be using is .items() or .values():
for key, value in json_object['data']['9'].items():
# We can use .keys() here since we only need the IDs from csevents
csevent_keys = list(value['csevents'].keys())
print(csevent_keys)
# Output
['2807', '2810']
['3601']

Accessing json array in python without referring to its name

I am new to python and I would like to understand how to access an array in a json object without referring to its name.
The given json object has the below structure
import json
input_json = {
"records": [
{
"values": {
"col1": "1"
},
"no": 1,
},
{
"values": {
"col1": "2"
},
"no": 2,
}
],
"number_of_records": 2
}
myVar = json.load(input_json)
for i in myVar['records']: # How do I replace this line?
print i['values']['col1']
I need to loop through the objects inside the 'records' array. How can I fetch the array without using myVar['records']?
Note that the code cannot depend on the order of the json attributes too. The only thing guaranteed is that the json string would have only one array in it.
input_json = {
"records": [
{
"values": {
"col1": "1"
},
"no": 1,
},
{
"values": {
"col1": "2"
},
"no": 2,
}
],
"number_of_records": 2
}
for anything in input_json:
if isinstance(input_json[anything], list):
for values in input_json[anything]:
print(values['values']['col1'])
You can also further nest the for loop if you don't know the 'values' and 'col1' names.

how to read specific values using Json to dict?

"Instances": [{
"nlu_classification": {
"Domain": "UDE",
"Intention": "Unspecified"
},
"nlu_interpretation_index": 1,
"nlu_slot_details": {
"Name": {
"literal": "ConnectedDrive"
},
"Search-phrase": {
"literal": "connecteddrive"
}
},
"interpretation_confidence": 5484
}],
"type": "nlu_results",
"api_version": "1.0"
}],
"nlps_version": "nlps(z):6.1.100.12.2-B359;Version: nlps-base-Zeppelin-6.1.100-B124-GMT20151130193521;"
}
},
"final_response": 1,
"prompt": "",
"result_format": "appserver_post_results"
}
I am getting the above code as a reply from the server. I am storing those result in the variable NLU_RESULT. later I am using json_loads to convert that json_format into dict and to check for the specific value within it as below.
parsed_json = json.loads(NLU_RESULT)
print(parsed_json["Instances"]["nlu_classification"]["Domain"]).
when I use the above code. Its not printing the value of Domain. Can someone tell me what is the mistake here ?
UPDATE
it should be something like
parsed['appserver_results']['payload']['actions'][0]['Instances'][0]['nlu_classification']['Domain']
the json you posted has instances as an array
so it should be something like
print(parsed_json["Instances"][0]["nlu_classification"]["Domain"])
also the json is a bit broken and contains some array closing without the array

grab values in json

I have the following json in this format:
{
"HATg": {
"id": "208-2",
"code": "225a"
"state" : True
},
"PROPEMPTY": {
"id": "208-3",
"code": "225b"
"state" False
}
}
Was wondering how do I access/grab both the id and code as I iterate each items in the file in a pythonic way? Like for i in items...
By the way, the contents in the json file differ as it is manipulate by user adding in different contents. Apologize in advance if I am not using any terms as I am not sure what they are called
Assuming your "JSON" looks more like this:
{
"HATg": {
"id": "208-2",
"code": "225a",
"state": true
},
"PROPEMPTY": {
"id": "208-3",
"code": "225b",
"state": false
}
}
and that you have succesfully parsed it into a Python object (for example, by using j = json.load(jsonfile)), then it's trivial to iterate through it in Python (assuming Python 3):
>>> for key, value in j.items():
... print("{}: {}, {}".format(key, value['id'], value['code']))
...
PROPEMPTY: 208-3, 225b
HATg: 208-2, 225a
What you have here is a python dictionary and not a json. You can iterate them like this:
a = {
"HATg": {
"id": "208-2",
"code": "225a",
"state" : True
},
"PROPEMPTY": {
"id": "208-3",
"code": "225b",
"state" : False
}
}
for i in a:
print i
print a[i]['id'], a[i]['code']
This will give the output as
PROPEMPTY
208-3 225b
HATg
208-2 225a

Extracting values from deeply nested JSON structures

This is a structure I'm getting from elsewhere, that is, a list of deeply nested dictionaries:
{
"foo_code": 404,
"foo_rbody": {
"query": {
"info": {
"acme_no": "444444",
"road_runner": "123"
},
"error": "no_lunch",
"message": "runner problem."
}
},
"acme_no": "444444",
"road_runner": "123",
"xyzzy_code": 200,
"xyzzy_rbody": {
"api": {
"items": [
{
"desc": "OK",
"id": 198,
"acme_no": "789",
"road_runner": "123",
"params": {
"bicycle": "2wheel",
"willie": "hungry",
"height": "1",
"coyote_id": "1511111"
},
"activity": "TRAP",
"state": "active",
"status": 200,
"type": "chase"
}
]
}
}
}
{
"foo_code": 200,
"foo_rbody": {
"query": {
"result": {
"acme_no": "260060730303258",
"road_runner": "123",
"abyss": "26843545600"
}
}
},
"acme_no": "260060730303258",
"road_runner": "123",
"xyzzy_code": 200,
"xyzzy_rbody": {
"api": {
"items": [
{
"desc": "OK",
"id": 198,
"acme_no": "789",
"road_runner": "123",
"params": {
"bicycle": "2wheel",
"willie": "hungry",
"height": "1",
"coyote_id": "1511111"
},
"activity": "TRAP",
"state": "active",
"status": 200,
"type": "chase"
}
]
}
}
}
Asking for different structures is out of question (legacy apis etc).
So I'm wondering if there's some clever way of extracting selected values from such a structure.
The candidates I was thinking of:
flatten particular dictionaries, building composite keys, smth like:
{
"foo_rbody.query.info.acme_no": "444444",
"foo_rbody.query.info.road_runner": "123",
...
}
Pro: getting every value with one access and if predictable key is not there, it means that the structure was not there (as you might have noticed, dictionaries may have different structures depending on whether it was successful operation, error happened, etc).
Con: what to do with lists?
Use some recursive function that would do successive key lookups, say by "foo_rbody", then by "query", "info", etc.
Any better candidates?
You can try this rather trivial function to access nested properties:
import re
def get_path(dct, path):
for i, p in re.findall(r'(\d+)|(\w+)', path):
dct = dct[p or int(i)]
return dct
Usage:
value = get_path(data, "xyzzy_rbody.api.items[0].params.bicycle")
Maybe the function byPath in my answer to this post might help you.
You could create your own path mechanism and then query the complicated dict with paths. Example:
/ : get the root object
/key: get the value of root_object['key'], e.g. /foo_code --> 404
/key/key: nesting: /foo_rbody/query/info/acme_no -> 444444
/key[i]: get ith element of that list, e.g. /xyzzy_rbody/api/items[0]/desc --> "OK"
The path can also return a dict which you then run more queries on, etc.
It would be fairly easy to implement recursively.
I think about two more solutions:
You can try package Pynq, described here - structured query language for JSON (in Python). As far as a I understand, it's some kind of LINQ for python.
You may also try to convert your JSON to XML and then use Xquery language to get data from it - XQuery library under Python

Categories

Resources