Python - Flatting Dictionary where some keys are 'missing'
Python - Flatting Dictionary where some keys are 'missing'
Is there a cleaner way to do this? I am checking a nested dictionary for a specific key and assigning that to a variable. I will be using it to make a mysql insert shortly.
My main issue is that if the key is not present (which sometimes happens) I dont want the code to fail, I just want to sent the variable to empty.
This code seems to work but I have to do something similar to about 20 differnt key values so I would like to make sure I am doing it the best way
if 'Model' in ItemAttributes:
Model=ItemAttributes['Model']['value']
else:
Model=''
3 Answers
3
Here is one solution:
Model = ItemAttributes.get('Model', {}).get('value', '')
If the "Model" key does not exist in the ItemAttributes
dictionary, you return an empty dictionary, on which you use dict.get('value', '')
. This will, of course, return an empty string if the "Model" key does not exist.
ItemAttributes
dict.get('value', '')
An alternative solution is to add an extra function call and have this function test for whether the key exists. Here we use a ternary statement. This is effectively what you are doing now, but wrapping the logic in a function for easy repeated access:
def get_value(d, key1, key2):
return d[key1][key2] if key1 in d else ''
Model = get_value(ItemAttributes, 'Model', 'value')
A more generic solution is to use try
/ except
and catch KeyError
. If any key is missing, the function will return an empty string. Otherwise, reduce
+ getitem
will cycle through the nested dictionary to access the appropriate value given a list of keys.
try
except
KeyError
reduce
getitem
from functools import reduce
from operator import getitem
def getFromDict(dataDict, mapList):
try:
return reduce(getitem, mapList, dataDict)
except KeyError:
return ''
Model = getFromDict(ItemAttributes, ['Model', 'Value'])
@personalt, There's a better solution, wait one moment :)
– jpp
Jul 1 at 17:01
@personalt, See the last solution. It'll work with any arbitrary list of keys representing the "path" you wish to take.
– jpp
Jul 1 at 17:08
model = ItemAttributes.get('Model', {}).get('value', '')
Not sure if it's much better, but it works! :)
Using get is often the best solution.
Another solution is to catch KeyError
exception:
KeyError
try:
Model=ItemAttributes['Model']['value']
except KeyError:
Model=''
Model will be set to ''
if 'Model'
is not in ItemAttributes
or if 'value'
is not in ItemAttributes['Model']
''
'Model'
ItemAttributes
'value'
ItemAttributes['Model']
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This is really nice as it makes it read a bit cleaner. To populate some of the variables I will be iterating 2 levels of dictionary deep. Others 3 and others 4.. So I would have to figure out how to modify this to accept variable number of arguments which may be beyond my skill but worth a shot
– personalt
Jul 1 at 17:00