The Python dictionary is one of the language’s most powerful data types. In other programming languages and computer science in general, dictionaries are also known as associative arrays. They allow you to associate one or more keys to values. If you are familiar with JSON, you might feel right at home. The syntax of a dictionary strongly resembles the syntax of a JSON document.
Table of Contents
Let’s look at how we can create and use a Python dictionary in the Python REPL:
>>> phone_numbers = < 'Jack': '070-02222748', 'Pete': '010-2488634' >>>> my_empty_dict = < >>>> phone_numbers['Jack'] '070-02222748'
A dictionary is created by using curly braces. Inside these braces, we can add one or more key-value pairs. The pairs are separated by commas when adding more than one key-value pair. The first dictionary in our example associates keys (names like Jack and Pete) with values (their phone numbers). The second dictionary is an empty one.
Now that you’ve seen how to initialize a dictionary, let’s see how we can add and remove entries to an already existing one:
>>> phone_numbers['Eric'] = '06-10101010' >>> del(phone_numbers['Jack']) >>> phone_numbersAnother way to retrieve a single value from a dictionary is using the get-method. The advantage? It returns a default value, None , if the key was not found. You can specify your own default value too.
With the get-method, you don’t have to surround the operation with a try… except. It’s ideal when working with configuration data that is parsed from YAML or JSON files, where your software offers defaults for unset configuration items.
>>> config = < 'host': 'example.org' >>>> config.get('port', 80) 80 >>> config.get('schema') >>>
That last get call returns None , but the more recent versions of the REPL don’t print None.
To overwrite an entry, simply assign a new value to it. You don’t need to del() it first. E.g.:
>>> phone_numbers = < 'Jack': '070-02222748', 'Pete': '010-2488634' >>>> phone_numbers['Jack'] = '1234567'
If a requested key does not exist, an exception of type KeyError is thrown:
>>> phone_numbers['lisa'] Traceback (most recent call last): File "", line 1, in KeyError: 'lisa'
If you know data can be missing, e.g., when parsing input from the outside world, make sure to surround your code with a try . except KeyError. I’ve explained this in detail in the best practices section of my article on try… except. In that article, I also explain the concept of asking for forgiveness, not permission. E.g., don’t check if a key exists before trying to access it. Instead, just try it, and catch the exception if it doesn’t exist.
You can put anything in a dictionary. You’re not limited to numbers or strings. In fact, you can put dictionaries and Python lists inside your dictionary and access the nested values in a very natural way:
>>> a = < 'sub_dict': < 'b': True >, 'mylist': [100, 200, 300] > >>> a['sub_dict']['b'] True >>> a['mylist'][0] 100
Python’s JSON decoding and encoding library uses this feature of Python when parsing more complex JSON documents. It creates nested trees of lists, dictionaries, and other valid data types.
You can go pretty wild on your dictionary keys, too. The only requirement is that the key is hashable. Mutable types like lists, dictionaries, and sets won’t work and result in an error like: TypeError: unhashable type: ‘dict’ .
Besides this limitation, you can use all data types as a dictionary key, including native types like a tuple, float and int or even a class name or object based on a class. Although completely useless for most, I’ll demonstrate anyway:
>>> my_dictionary = < int: 1, float: 2, dict: 3 >>>> my_dictionary[dict] 3 >>> class P: . pass . >>> my_dictionary[P]=1 >>> p = P() >>> my_dictionary[p]=2
A more likely use case is the use of numbers as keys. For example, consider this registration of runners in a marathon:
>>> runners = < 1000: 'Jack', 1001: 'Eric', 1002: 'Lisa' >>>> runners[1001] 'Eric'
Depending on your data source, there are more advanced ways to initialize a dictionary that might come in handy.
The dict() function builds a dictionary from a sequence or list of key-value pairs (tuples):
>>> dict([ ('Jack', '070-02222748'), ('Pete', '010-2488634'), ('Eric', '06-10101010') ])Analogous to list comprehensions, you can also use dictionary comprehensions to create a new dictionary. While a list only contains values, a dictionary contains key/value pairs. Hence, dictionary comprehensions need to define both. Other than that, the syntax is similar:
Please read my article on list comprehensions for a more detailed explanation of comprehensions in general.
The dict.fromkeys(keys, value) method creates a new dictionary, based on the list of keys supplied to it. The value of all elements will be set to the supplied value , or None by default, if you don’t supply a value.
See the following code:
>>> names = ['Eric', 'Martha', 'Ellen'] >>> phone_numbers = dict.fromkeys(names, None) >>> phone_numbersThe list of keys can be anything that is iterable. E.g., this works just as well with a set or a tuple.
As explained in the section on working with JSON, you can also decode JSON data into a dictionary like this:
>>> import json >>> jsonstring = '< "name": "erik", "age": 38, "married": true>' >>> json.loads(jsonstring)You can check if a key exists inside a dictionary with the in and not in keywords:
>>> 'Jack' in phone_numbers True >>> 'Jack' not in phone_numbers False
The built-in Python len() function returns the number of key/value pairs in a dictionary:
>>> phone_numbers = < 'Jack': '070-02222748', 'Pete': '010-2488634', 'Eric': '06-10101010' >>>> len(phone_numbers) 3
Some built-in dictionary methods return a view object, offering a window on your dictionary’s keys and values. Before we start using such view objects, there’s an important concept you need to understand: values in a view object change as the content of the dictionary changes.
This is best illustrated with an example, in which we use two of these views: keys() and values(). Keys returns a view on all the keys of a dictionary, while values() returns a view on all its values:
If that didn’t work, here’s the non-interactive version:
phone_numbers = < 'Jack': '070-02222748', 'Pete': '010-2488634', 'Eric': '06-10101010' >names = phone_numbers.keys() numbers = phone_numbers.values() phone_numbers['Linda'] = '030-987612312' print(names) print(numbers) # Loop through a view object with: for number in numbers: print(number)
The output of this code is dict_keys(['Jack', 'Pete', 'Eric', 'Linda']) . As you can see, Linda is part of the list too, even though she got added after creating the names view object.
The items() method of a dictionary returns an iterable view object, offering both the keys and values, as can be seen below. You can loop through this object with a simple Python for-loop:
>>> phone_numbers.items() dict_items([('Jack', '070-02222748'), ('Pete', '010-2488634'), ('Eric', '06-10101010')]) >>> for name, phonenr in phone_numbers.items(): . print(name, ":", phonenr) . Jack : 070-02222748 Pete : 010-2488634 Eric : 06-10101010
Alternatively, you can use the keys() and values() methods to loop through just the keys or values. Both functions return an iterable view object.
We’ve seen the dict.keys() method, which returns a view object containing a list of all the dictionary keys. The advantage of this object is that it stays in sync with the dictionary. It’s perfect for looping over all the keys, but you still might opt for the list or sorted methods though, because those return a native list that you can manipulate as well.
There are two other easy ways to get all the keys from a dictionary:
>>> phone_numbers = < 'Jack': '070-02222748', 'Pete': '010-2488634', 'Eric': '06-10101010' >>>> list(phone_numbers) ['Jack', 'Pete', 'Eric'] >>> sorted(phone_numbers) ['Eric', 'Jack', 'Pete']
list() returns all the keys in insertion order, while sorted() returns all the keys sorted alphabetically.
If you’re running Python 3.9 or later, you can use the newly introduced merging operator for dictionaries:
merged = dict1 | dict2
If you’re still on a Python version between 3.5 and 3.9, you can merge two dictionaries using the following method:
dict1 = < 'a': 1, 'b': 2 >dict2 = < 'b': 3, 'c': 4 >merged = < **dict1, **dict2 >print (merged) #If you need to compare two dictionaries, you can use a comparison operator like this:
>>> first_dict = < 'a': 1, 'b': 2, 'c': 'a string' >>>> second_dict = < 'a': 1, 'b': 2, 'c': 'a string' >>>> first_dict == second_dict True
This looks and sounds trivial, but it’s not! A dictionary can contain objects of any type, after all! Consequently, Python has to walk through all the keys and values and individually compare them.
You might wonder if a dictionary with the same keys and values inserted in another order is the same. Let’s check this:
>>> first_dict = < 'a': 1, 'b': 2, 'c': 'a string' >>>> second_dict = < 'b': 2, 'a': 1, 'c': 'a string' >>>> first_dict == second_dict True
They are the same to Python, despite having a different order.
Good to know: the order of dictionaries is guaranteed to be insertion order since Python 3.7. In other words, it means that the order of the dictionary is determined by the order in which you insert items.
Each dictionary inherits some handy built-in functions, as listed in the following table:
Method | What is does | Example |
---|---|---|
clear() | Remove all key/value pairs (empty the dictionary) | phone_numbers.clear() |
get(key) | Get a single item with the given key, with an optional default value | phone_numbers.get('Martha', 'Unknown person') |
items() | Returns a view object containing key-value pairs from the dictionary | phone_numbers.items() |
keys() | Returns a view object with a list of all keys from the dictionary | phone_numbers.keys() |
values() | Returns a view_object with a list of all values from the dictionary | phone_numbers.values() |
pop(key, default_value) | Returns and removes the element with the specified key | phone_numbers.pop('Martha') |
popitem() | Returns and removes the last inserted item (Python 3.7+) or a random item | phone_numbers.popitem() |
setdefault(key, value) | Returns the value of the specified key. If the key does not exist, it’s inserted with the given value | phone_numbers.setdefault('John Doe', 1234) |
update(iterable) | Add all pairs from given iterable, e.g. a dictionary | Add all pairs from a given iterable, e.g. a dictionary |
You’ve learned what a Python dictionary is, how to create dictionaries, and how to use them. We’ve examined many practical use cases involving Python dictionaries with example code. If there’s still something missing, or you simply want to learn even more about dictionaries, you can head over to the official manual page at Python.org.
Learn Python properly through small, easy-to-digest lessons, progress tracking, quizzes to test your knowledge, and practice sessions. Each course will earn you a downloadable course certificate.
Sale Product on sale Beginners Python Course (2024) € 59.00 Original price was: € 59.00. Current price is: € 39.00. Sale Product on sale Files, Folders, And The Command Line (2024) € 39.00 Original price was: € 39.00. Current price is: € 19.00. Sale Product on sale Modules, Packages, And Virtual Environments (2024) € 59.00 Original price was: € 59.00. Current price is: € 39.00.