Skip to content

A Comprehensive Guide to Dictionaries in Python: Accessing Values by Keys and Handling Key Errors

Updated: at 04:12 AM

Dictionaries are a fundamental data structure in Python used to store data values mapped to unique keys. Dictionaries are implemented using hash tables, providing efficient lookup time and the ability to store different data types. Mastering dictionaries is key to unlocking Python’s versatility in data manipulation and modeling.

This comprehensive guide will explain everything you need to know about accessing values in a Python dictionary by keys and properly handling key errors. We will cover key concepts and techniques related to dictionaries including:

Table of Contents

Open Table of Contents

Dictionary Basics

Dictionaries in Python are mutable collections that store mappings of unique keys to values. Dictionaries are denoted with curly braces {} and have key-value pairs separated by commas ,.

dict_1 = {'key1': 'value1', 'key2': 'value2'}

The key can be any immutable Python data type like strings, numbers or tuples. Values can be any Python object. Accessing values is done by square bracket notation with the key.

print(dict_1['key1']) # 'value1'

Dictionaries are dynamic and new key-value pairs can be added simply by assignment.

dict_1['key3'] = 'value3'
print(dict_1)

# {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

Built-in functions like len(), sorted(), min(), max() work on dictionaries to return information about the keys.

Keys in Dictionaries

Keys in dictionaries must be unique and immutable - meaning unchangeable. Immutable types in Python include strings, integers, floats, tuples etc. Lists and dictionaries cannot be used as keys.

Keys enable efficient lookup time by using hashing functions internally. Hashing requires the key to be immutable so its hash value can be cached for quick lookups in the dictionary’s hash table structure.

Trying to use a mutable object like a list as a key will result in a TypeError:

dict_2 = {[1,2]: 'value'}
# TypeError: unhashable type: 'list'

String, numeric and tuple keys are commonly used:

dict_2 = {'name': 'John', 1: 'one', (1,2): 'tuple'}

Accessing Values by Key

Values can be accessed by square bracket notation using the key. This returns the value for the specified key if found, otherwise a KeyError occurs.

dict_3 = {'name': 'Susan', 'age': 28}

print(dict_3['name']) # Susan
print(dict_3['age']) # 28

The get() method is an alternative, safer way to lookup values:

print(dict_3.get('name')) # Susan
print(dict_3.get('salary')) # None

get() has two advantages compared to the square brackets:

  1. It does not raise a KeyError if the key is missing - it returns None instead.

  2. A default return value can be specified instead of None:

dict_3.get('age', 0) # 28
dict_3.get('salary', 0) # 0 (default)

This provides an easy way to safely handle missing keys.

Key Errors in Python Dictionaries

A KeyError occurs when trying to access a dictionary value using a key that does not exist:

dict_4 = {'name': 'Bob'}

print(dict_4['age'])
# KeyError: 'age'

This usually indicates a bug in code logic or invalid assumptions about data. Key errors crash programs so they need to be handled properly.

The best way is to catch and handle the exception gracefully using try/except:

try:
  print(dict_4['age'])
except KeyError:
  print('Key age does not exist')
# Key age does not exist

This prevents the crash and executes custom logic when the missing key is accessed.

Alternatively, check if keys exist before accessing them using the in operator or get():

if 'age' in dict_4:
  print(dict_4['age'])
else:
  print('Key age does not exist')

# Key age does not exist

Defensive programming with try/except blocks or key checking helps make code more robust and prevent errors.

Checking If a Key Exists

Instead of handling key errors after they occur, it is better to proactively check if a key exists before accessing it.

The in operator checks if a key exists in a dictionary:

dict_5 = {'name': 'Maria', 'age': 31}

print('name' in dict_5) # True
print('salary' in dict_5) # False

This returns a boolean indicating if the key is found. It can be used to conditionally access values if the key exists:

if 'age' in dict_5:
  print(dict_5['age']) # 31

The get() method is another way to check keys by seeing if it returns the default value:

print(dict_5.get('salary') is None) # True
print(dict_5.get('name') is None) # False

These allow checking for keys existence without generating errors.

Setting Default Dictionary Values

When accessing a non-existent key, you may want to set a default value in the dictionary automatically.

The setdefault() method is one way to do this:

dict_6.setdefault('name', 'Unknown') # 'Unknown'
dict_6.setdefault('name', 'John') # 'John' (no change)

print(dict_6)
# {'name': 'John'}

It sets the value if the key does not exist yet. Otherwise it returns the existing value.

Another option is using defaultdict from the collections module:

from collections import defaultdict

dict_def = defaultdict(int)
dict_def['count'] # 0 (default)
dict_def['count'] += 1

print(dict_def)
# {'count': 1}

This automatically sets the default when keys are accessed.

Common Dictionary Methods

There are many helpful dictionary methods for common operations:

These provide functionality like fetching all keys or values, copying, merging, and deleting dictionary elements.

Dictionaries are a versatile data structure central to many Python programs. Mastering key concepts like access by keys, handling key errors, and dictionary methods unlocks the ability to use dictionaries for data manipulation in your code.

Conclusion

This guide covered comprehensive details on how to access values in Python dictionaries by key and handle key errors properly. The key takeaways include:

With this knowledge, you can leverage dictionaries in your Python code for modeling data and efficiently accessing values. Dictionaries are fundamental to many programming techniques in Python including memoization, sets, data science and more. Mastering their usage unlocks the real power and versatility of Python.

The next step is to practically apply these dictionary concepts in your own code. Try creating dictionaries, accessing values, handling errors, and using methods to grow familiar with dictionary programming. Python’s built-in documentation and online resources can help further your learning. This will build expertise using one of Python’s most useful data structures.