Last updated: Apr 10, 2024
Reading timeยท6 min
Note: If you need to remove keys from a nested dictionary, click on the following subheading:
Use a try/except
statement to check if a nested key exists in a
dictionary.
If one or more of the nested keys doesn't exist, a KeyError
is raised and is
then handled by the except
block.
my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu' } } try: city = my_dict['address']['city'] print(city) # ๐๏ธ Oulu except KeyError: print('The specified key does NOT exist') # ------------------------------------------------- try: result = my_dict['not']['found']['key'] except KeyError: # ๐๏ธ this runs print('The specified key does NOT exist')
We try to access a nested key in the try
block of the try/except
statement.
If one of the keys doesn't exist, a KeyError
exception is raised and is then
handled by the except
block.
You can use a pass
statement if you need to ignore the exception.
my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu' } } try: result = my_dict['not']['found']['key'] except KeyError: pass
The pass statement does nothing and is used when a statement is required syntactically but the program requires no action.
If you have to do this often, extract the logic into a reusable function.
def keys_exists(dictionary, keys): nested_dict = dictionary for key in keys: try: nested_dict = nested_dict[key] except KeyError: return False return True my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu' } } # ๐๏ธ True print( keys_exists(my_dict, ['address', 'city']) ) # ๐๏ธ False print( keys_exists(my_dict, ['key', 'not', 'found']) )
The function takes a dictionary and a list of keys and checks if the sequence of keys exist in the dictionary.
We iterate over the list of keys and try to access each nested key, so the order of the keys in the list is important.
The function returns True
if the sequence of keys exists in the dictionary,
otherwise False
is returned.
Alternatively, you can use the dict.get()
method.
This is a three-step process:
dict.get()
method to get each key.dict.get()
method as necessary.my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu' } } result = my_dict.get('address', {}).get('city') print(result) # ๐๏ธ Oulu result = my_dict.get('key', {}).get('not', {}).get('found') print(result) # ๐๏ธ None
The dict.get method returns the value for the given key if the key is in the dictionary, otherwise a default value is returned.
The method takes the following 2 parameters:
Name | Description |
---|---|
key | The key for which to return the value |
default | The default value to be returned if the provided key is not present in the dictionary (optional) |
If a value for the default
parameter is not provided, it defaults to None
,
so the get()
method never raises a KeyError
.
dict.get()
method, so we can chain multiple calls to the method even if the nested key doesn't exist.If the specified key doesn't exist an empty dictionary is returned on which we
can safely call the dict.get()
method again.
You don't have to pass an empty dictionary in the last call to dict.get()
because the method returns None if a default value
is not provided and the key doesn't exist.
my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu' } } result = my_dict.get('key', {}).get('not', {}).get('found') print(result) # ๐๏ธ None
Which approach you pick is a matter of personal preference. I'd use a
try/except
statement because I find them quite direct and easy to read.
To remove keys from a nested dictionary:
for
loop to iterate over the collection of keys to remove.def remove_nested_keys(dictionary, keys_to_remove): for key in keys_to_remove: if key in dictionary: del dictionary[key] for value in dictionary.values(): if isinstance(value, dict): remove_nested_keys(value, keys_to_remove) return dictionary my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu', }, 'name': 'Frank', 'age': 30, } # ๐๏ธ {'address': {'country': 'Finland'}, 'name': 'Frank'} print(remove_nested_keys(my_dict, ['city', 'age']))
We created a reusable function that takes a dictionary and a list of keys and removes the specified nested and non-nested keys from the dictionary.
The first step is to iterate over the list of keys to be removed.
for key in keys_to_remove: if key in dictionary: del dictionary[key]
On each iteration, we check if the key is present in the dictionary and if the condition is met, we remove the key.
in
operator checks for the existence of the specified key in the dict
object.This for loop takes care of removing all of the specified non-nested keys.
The next step is to iterate over the dictionary's values.
for value in dictionary.values(): if isinstance(value, dict): remove_nested_keys(value, keys_to_remove)
The dict.values method returns a new view of the dictionary's values.
my_dict = {'id': 1, 'name': 'bobbyhadz'} print(my_dict.values()) # ๐๏ธ dict_values([1, 'bobbyhadz'])
remove_nested_keys
function with the nested dictionary and the list of keys to remove.Then the function iterates over the list of keys again and uses the del
to
remove the specified keys.
The isinstance function returns
True
if the passed-in object is an instance or a subclass of the passed-in
class.
# ๐๏ธ True print( isinstance({'site': 'bobbyhadz.com'}, dict) ) # ๐๏ธ False print( isinstance(['a', 'b', 'c'], dict) )
The function removes the keys from the nested dictionary in place. In other
words, it mutates the original dict
object.
If you'd rather not mutate the original dictionary:
for
loop to iterate over the dictionary's items.# โ function returns new dictionary (does NOT mutate original) def remove_nested_keys(dictionary, keys_to_remove): new_dict = {} for key, value in dictionary.items(): if key not in keys_to_remove: if isinstance(value, dict): new_dict[key] = remove_nested_keys(value, keys_to_remove) else: new_dict[key] = value return new_dict my_dict = { 'address': { 'country': 'Finland', 'city': 'Oulu', }, 'name': 'Frank', 'age': 30, } result = remove_nested_keys(my_dict, ['country', 'name']) print(result) # ๐๏ธ {'address': {'city': 'Oulu'}, 'age': 30} result = remove_nested_keys(my_dict, ['city', 'age']) print(result) # ๐๏ธ {'address': {'country': 'Finland'}, 'name': 'Frank'}
We used a for
loop to iterate over the dictionary's items.
The dict.items method returns a new view of the dictionary's items ((key, value) pairs).
my_dict = {'id': 1, 'name': 'BobbyHadz'} # ๐๏ธ dict_items([('id', 1), ('name', 'BobbyHadz')]) print(my_dict.items())
On each iteration, we check if the current key is not one of the keys to be removed.
for key, value in dictionary.items(): if key not in keys_to_remove: if isinstance(value, dict): new_dict[key] = remove_nested_keys(value, keys_to_remove) else: new_dict[key] = value
The isinstance()
function then checks if the key points to a dictionary value.
If the key stores a dictionary, the remove_nested_keys
function is invoked
with the nested dictionary and the list of keys to remove.
If the key doesn't store a dictionary, the key-value pair gets added to the new dictionary.
The function returns the newly constructed dictionary excluding all of the keys in the list.
You can learn more about the related topics by checking out the following tutorials: