by Chris Ried
Stop Accessing dictionary items by index
Best practice on how to access dictionary items in Python
The problem #
Since most of us are lazy programmers, it's more convenient to access items from a Python dictionary by index like this: my_dict[key].
Warning: Accessing items from a dictionary by index could return a KeyError
exception if the key is missing and will break the flow of your application.
Even though this might seem small and irrelevant, it's really annoying when it happens, especially if you have a big and complex application, since this method will break the flow.
Traceback (most recent call last): File "<input>", line 1, in <module> KeyError: '<KEY_NAME>'
Workarounds#
One might argue you can wrap a piece of code with the try
statement, or use top-level error handlers
on your service, but why do this when you can prevent all of this overhead by using a build-in method instead?
Best Practice#
Best Practise: get(key[, default])
From the Python Official Documentation
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults toNone
, so that this method never raises aKeyError
.
This is the safest choice since the .get()
method will return None
if the key is not in the dictionary. But again, be careful, you should always design your system to handle the None
scenarios as well.
Using this method you have more flexibility as to what to return if the key is missing. By default, this method will return None. You could also specify a different default value or even a callback.
d = {'key1': 1, 'key2': 2}
# Returns None
d.get('new')
# Returns 6
some_number = 6
d.get('new', some_number)
def callback():
return 2
# Returns the function output
d.get('new', callback())
Create your custom Dictionary#
Well, if you are still stubborn and still want to access your items by index, there is still a way. You can create your own version of the dictionary. You can create a new class that inherits the dict
and implement the __missing__
function in order to return something when the key is not found.
If you decide to mimic the same functionality as the get(key)
method, you can use the example below:
class CustomDict(dict):
def __missing__(self, key):
return None
By doing so, you ensure that if the key does not exist, the method will return None instead of raising a KeyError exception. You can also be creative and do something that fits your own requirements. If you decide to return the max value you currently have in your dictionary you can do the following:
class CustomDict(dict):
def __missing__(self, key):
return max(self.values())
d = CustomDict()
d.update({
'key1':1,
'key2':2
})
# Will print 2
print(d['new_key'])