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'])





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





@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 KeyErrorexception:


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.

Popular posts from this blog

How to make file upload 'Required' in Contact Form 7?

Rothschild family

amazon EC2 - How to make wp-config.php to writable?