This is an old question with accepted answer, but I would do this using nested if statements instead.
import json
json = json.loads('{ "A": { "B": { "C": {"D": "yes"} } } }')
if 'A' in json:
if 'B' in json['A']:
if 'C' in json['A']['B']:
print(json['A']['B']['C']) #or whatever you want to do
or if you know that you always have 'A' and 'B':
import json
json = json.loads('{ "A": { "B": { "C": {"D": "yes"} } } }')
if 'C' in json['A']['B']:
print(json['A']['B']['C']) #or whatever
Answer from Daniel Zakrisson on Stack OverflowThis is an old question with accepted answer, but I would do this using nested if statements instead.
import json
json = json.loads('{ "A": { "B": { "C": {"D": "yes"} } } }')
if 'A' in json:
if 'B' in json['A']:
if 'C' in json['A']['B']:
print(json['A']['B']['C']) #or whatever you want to do
or if you know that you always have 'A' and 'B':
import json
json = json.loads('{ "A": { "B": { "C": {"D": "yes"} } } }')
if 'C' in json['A']['B']:
print(json['A']['B']['C']) #or whatever
An quite easy and comfortable way is to use the package python-benedict with full keypath support. Therefore, cast your existing dict d with the function benedict():
d = benedict(d)
Now your dict has full key path support and you can check if the key exists in the pythonic way, using the in operator:
if 'mainsnak.datavalue.value.numeric-id' in d:
# do something
Please find here the complete documentation.
Python to check existence of nested JSON key-value - Stack Overflow
python - Elegant way to check if a nested key exists in a dict? - Stack Overflow
How to check if something is in a JSON object before running if statement
Check if key exists and iterate the JSON array using Python - Stack Overflow
I have the following json structure file:
parent1 -------subcat1 ----------------subsubcat1 ----------------.... ----------------subsubcatN -------.... -------subcatN parent2 -------subcat1 ----------------subsubcat1 ----------------.... ----------------subsubcatN -------.... -------subcatN
and each subsubcat has list of dictionaries in which one key - value pair can be 'uid':'12563'.
I need to check if parent1, parent2 has this par, or none of them... problem i subcat and subsubcat keys are not consistent (they change depending on json file), deepness stays the same.
Basically i need smng like
if json['parent1][*][*][*]['uid'] == 12563
but it's not gonna work :)
To be brief, with Python you must trust it is easier to ask for forgiveness than permission
try:
x = s['mainsnak']['datavalue']['value']['numeric-id']
except KeyError:
pass
The answer
Here is how I deal with nested dict keys:
def keys_exists(element, *keys):
'''
Check if *keys (nested) exists in `element` (dict).
'''
if not isinstance(element, dict):
raise AttributeError('keys_exists() expects dict as first argument.')
if len(keys) == 0:
raise AttributeError('keys_exists() expects at least two arguments, one given.')
_element = element
for key in keys:
try:
_element = _element[key]
except KeyError:
return False
return True
Example:
data = {
"spam": {
"egg": {
"bacon": "Well..",
"sausages": "Spam egg sausages and spam",
"spam": "does not have much spam in it"
}
}
}
print 'spam (exists): {}'.format(keys_exists(data, "spam"))
print 'spam > bacon (do not exists): {}'.format(keys_exists(data, "spam", "bacon"))
print 'spam > egg (exists): {}'.format(keys_exists(data, "spam", "egg"))
print 'spam > egg > bacon (exists): {}'.format(keys_exists(data, "spam", "egg", "bacon"))
Output:
spam (exists): True
spam > bacon (do not exists): False
spam > egg (exists): True
spam > egg > bacon (exists): True
It loop in given element testing each key in given order.
I prefere this to all variable.get('key', {}) methods I found because it follows EAFP.
Function except to be called like: keys_exists(dict_element_to_test, 'key_level_0', 'key_level_1', 'key_level_n', ..). At least two arguments are required, the element and one key, but you can add how many keys you want.
If you need to use kind of map, you can do something like:
expected_keys = ['spam', 'egg', 'bacon']
keys_exists(data, *expected_keys)
You could use .get with defaults:
s.get('mainsnak', {}).get('datavalue', {}).get('value', {}).get('numeric-id')
but this is almost certainly less clear than using try/except.
Ok... This is a little complicated... So... Sorry in advance
I have a function that returns attributes of a video file (FFprobe) in a JSON object, and then a little factory that parses the JSON looking for specific attributes, and running if statements on those attributes.
I.E. One of attributes in the JSON is subtitle format. So if the subtitle format != a desired format, then set a variable that is used in another format for encoding the subtitle to the desired format
The issue that I have run into so that sometimes those attributes (like subtitle) don't exist in the JSON because they do not exist in the file.
So I sort of need to check if the attribute in the JSON exists, before I check to see if if that attribute is the desired attribute and start setting variables
How do I do this?
Would it be as simple as:
json_object= json.loads(studentJson)
if "subtitle_format" in json_object:
print("Key exist in json_object")
print(subtitle_format["ASS"], " is the subtitle format")
else:
print("Key doesn't exist in JSON data")If yes, would I get yelled at if the if statement had a few layers? Psudo:
if subtitle_format in json_object:
if subtitle_format == ass
if subtitle_format == english
encode
import json
jsonData = """{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}"""
def getTargetIds(jsonData):
data = json.loads(jsonData)
if 'to' not in data:
raise ValueError("No target in given data")
if 'data' not in data['to']:
raise ValueError("No data for target")
for dest in data['to']['data']:
if 'id' not in dest:
continue
targetId = dest['id']
print("to_id:", targetId)
Output:
In [9]: getTargetIds(s)
to_id: 1543
If all you want is to check if key exists or not
h = {'a': 1}
'b' in h # returns False
If you want to check if there is a value for key
h.get('b') # returns None
Return a default value if actual value is missing
h.get('b', 'Default value')
Using your code, if I understand you correctly, you could just do something like this:
r = requests.get(f'https://api.vlb.de/api/v2/product/{isbn}/ean?access_token=9xx9xxxxxc9')
vlb = json.loads(r.text)
neupreis = "False"
for i in vlb['prices']:
if i['priceType'] == "04" and i["countriesIncluded"] == "DE":
neupreis = i['priceAmount']
break
A different approach would be to use a list-comprehension like this:
neupreise = [i['priceAmount'] for i in vlb["prices"] if i['priceType'] == "04" and i["countriesIncluded"] == "DE"]
In this case all the priceAmounts for the prices that meet the criterium are saved in a list. If the list is empty, then none of them met the criterium.
This should help if you want to check if you don't want the last forloop to silently do nothing you can add before the second loop if indexes:
r = requests.get(f'https://api.vlb.de/api/v2/product/{isbn}/ean?access_token=9xx9xxxxxc9')
vlb = json.loads(r.text)
indexes=[]
for i, preisDict in enumerate(vlb['prices']):
if preisDict['priceType'] == "04" and preisDict["countriesIncluded"] == "DE":
#neupreis = preisDict['priceAmount']
indexes.append(i)
# Now you can access the Prices which meets the condition using
for i in indexes: # Will silently do nothing if the is not any which matches the condition
vlb['prices'][i] # then do something with the right pricetypes