Python Dictionaries: A Complete Guide
Tags: python, datascience, webdev
Published: 2022-10-01 17:15:07

Dictionaries are an important way to store data in Python. They let us store information as key value pairs which are indexed by key name rather than index like in [Python Lists](https://fjolt.com/article/python-lists). In this guide we will cover everything you need to know about Python dictionaries. If you are interested in other data collections in Python, such as lists, sets and tuples, [you can find out more about them here](https://fjolt.com/article/python-data-collections).

Let's begin by defining a dictionary. We use curly brackets, just like in [Python sets](https://fjolt.com/article/python-sets) - but we define both keys and values, which is slightly different than sets:
```python
dictionary = { "name" : "Johnny", "age" : 152 }
```

While this methods of creating dictionaries are great, we are not limited by them. If you are familiar with [Python lists](https://fjolt.com/article/python-lists), you can turn them straight into dictionaries using the `dict()` function:
```python
dictionary = dict([['name', 'Johnny'], ['age', 152]])
print(dictionary) # { "name" : "Johnny", "age" : 152 }
```

Or, we can use the `dict` function to create a dictionary from variables:
```python
dictionary = dict(name="Johnny", age=153)
print(dictionary) # { "name" : "Johnny", "age" : 152 }
```

Accessing Python dictionary values can be accessed using the square bracket notation:
```python
dictionary = { "name" : "Johnny", "age" : 152 }
print(dictionary["name"]) # Johnny

```
Or, if you want, you can get this information using the `get` method:
```python
dictionary = { "name" : "Johnny", "age" : 152 }
print(dictionary.get("name")) # Johnny
```

Python dictionaries are also mutable, so using the square bracket notation above, we can update values:
```python
dictionary = { "name" : "Johnny", "age" : 152 }
dictionary["age"] = 153

print(dictionary["age"]) # 153
```

Or, you can use the `update()` method, based on your preference:
```python
dictionary = { "name" : "Johnny", "age" : 152 }
dictionary.update({"age" : 153})

print(dictionary["age"]) # 153
```

Dictionaries can also be multidimensional. So this is also a valid dictionary:
```python
dictionary = {
    "name" : {
        "firstName" : "Johnny",
        "lastName" : "Simpson"
    },
    "age": 152
}
```
Finally, you can get the length of a dictionary (i.e. the number of key value pairs) using the `len()` function:
```python
dictionary = { "name" : "Johnny", "age" : 152 }
dictionary.update("age", 153)

print(len(dictionary)) # 2
```

## Python Dictionary Methods
We've covered both `get` and `update` so far, but there are a bunch of other methods which are useful too. Here's a full list of them:
- `dict.clear()` - deletes all items from a python dictionary.
- `dict.copy()` - makes a copy of a dictionary, which has the same value, but a different reference.
- `dict.popitem()` - removes the last key value pair from the dictionary.
- `dict.pop("keyItem")` - removes the key value pair with a key of "keyItem".
- `dict.update(newDictionary)` - updates the dictionary with keys and values from `newDictionary`, overwriting any existing ones.
- `dict.setdefault("key", "default")` - will return the value for the item `key`, and if it doesn't exist, will create a new key value pair of `{'key' : 'default'}`
- `dict.fromkeys(keys, values)` - takes two sets of data for both `keys` and `values`, and creates a new dictionary based off them.
- `dict.items()` - returns an iterable set of tuples for each key value pair. The returned data is known as a **view object**.
- `dict.keys()` - returns an iterable set of keys for the dictionary. The returned data is known as a **view object**.
- `dict.values()` - returns an iterable set of values for the dictionary. The returned data is known as a **view object**.


### View Objects in Python Dictionaries
You might notice that the last three methods, `items()`, `keys()`, and `values()`, all return a **view object**. A view object are a dynamic way type of object which will update automatically should the dictionary be updated. They are also iterable. Let's look at a quick example, using `dict.items()`:
```python
dictionary = dict(name="Johnny", age=153)
getDictionaryItems = dictionary.items()

for x in setDictionary:
    print(x) 

# Returns 
# ('name', 'Johnny')
# ('age', 153)
```

`dict.items()` returns a list of tuples, so we can easily iterate over them using a `for` loop.

View Objects also support membership checks. For example, we can check if a certain key exists in a dictionary using the `keys()` method, along with the `in` and `not in` operators:
```python
dictionary = dict(name="Johnny", age=153)
getDictionaryItems = dictionary.keys()

print("name" in getDictionaryItems) # True, as name is a key in dictionary
print("name" not in getDictionaryItems) # False, as name is a key in dictionary
```

### Deleting Items from Dictionaries in Python
There are a number of ways to delete items from a dictionary, as shown in the methods list above. The main ones are `popitem()`, `pop()`, and `clear()`. Let's look at a few examples, so it's clear how they work. To remove a specific item from a dictionary, we use `pop`. In the example below, I remove the dictionary item with the key `favouriteDrink`:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")
dictionary.pop("favouriteDrink")
print(dictionary) # {'name': 'Johnny', 'age': 153}
```

If methods aren't your thing, you can just use the `del` keyword to remove `favouriteDrink` in the same way:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")
del dictionary["favouriteDrink"]
print(dictionary) # {'name': 'Johnny', 'age': 153}
```

If we only wanted to remove the last item, without specifying it, we can use `popitem`:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")
dictionary.popitem()
print(dictionary) # {'name': 'Johnny', 'age': 153}
```


Or if we wanted to clear the dictionary completely, we can use `clear()`:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")
dictionary.clear()
print(dictionary) # {}
```

### Using setdefault with Python Dictionaries
The `setdefault` method on Python dictionaries either returns a value for a key if it exists, or creates that key value pair if it doesn't. The first argument is the key, and the second is the value you wish to set the key to should it not exist - for example, `dict.setdefault("age", 152)`. If you do not set the second argument, it defaults to the string `None`.

Here is an example, which leads to a new key value pair being added to the object dictionary below:
```python
dictionary = { "name" : "Johnny", "age": 152 }

dictionary.setdefault("age", 152) # Does nothing but returns age, as age exists on dictionary
dictionary.setdefault("favouriteDrink", "tea") # Adds `favouriteDrink` to dictionary
print(dictionary) # {'name': 'Johnny', 'age': 152, 'favouriteDrink': 'tea'}
```

### Creating a New Dictionary from two lists of data in Python
If you wish to create a new dictionary in python from a set of data, we can use the `dict.fromkeys` method. Here, we can define a list, set or tuple of data for keys, and a single value for the value that each key should be. For example, below I've defined a [tuple](https://fjolt.com/article/python-tuples) and a single value of `1`. When combined with `fromkeys`, we get a brand new dictionary:
```python
myKeys = ("name", "age", "favouriteDrink")
myValues = 1

newDict = dict.fromkeys(myKeys, myValues)

print(newDict) # {'name': 1, 'age': 1, 'favouriteDrink': 1}
```

## Iterating Over a Dictionaries Keys
An easy way to iterate over a dictionaries keys, along with the `dict.keys()` method, is to simply call `iter()`, which returns an iterable for the keys in your dictionary. This essentially performs the same task as `dict.keys()` **most of the time**:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")

dictKeys = iter(dictionary)

for x in dictKeys:
    print(x)

# Returns name age favouriteDrink
```

The difference between `iter` and `dict.keys()`, is you **cannot** alter the keys after calling iter. To show you what I mean, below I add a new key after calling `iter` and try to iterate over with a `for` loop. This produces an error, as the keys changed during iteration:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")
dictKeys = iter(dictionary)

dictionary['birthday'] = "Monday"
for x in dictKeys:
    print(x)

# RuntimeError: dictionary changed size during iteration
```

Meanwhile, no error will be produced for `dict.keys()`, since `dict.keys()` produces a view object which is a dynamic live view of the dictionaries contents:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")
dictKeys = dictionary.keys()

dictionary['birthday'] = "Monday"
for x in dictKeys:
    print(x)

# Returns name age favouriteDrink birthday
```

### Iterating Over a Dictionaries Keys in Reverse Order
Another useful function you might find yourself using is `reversed`. This function takes a dictionaries keys, and returns an iterable list of them in reverse order. As with `iter`, you will product errors if you try to update the dictionary while iterating over it in `reversed` form. 

Once reversed, the keys can be iterated upon to do some function of your choosing. Here is an example, which returns the string value of each key in reverse order for `dictionary`:
```python
dictionary = dict(name="Johnny", age=153, favouriteDrink="tea")

reversedDict = reversed(dictionary)

for x in reversedDict:
    print(x)

# Returns favouriteDrink age name
```

## Checking Membership in a Python Dictionary
Just like in [sets](https://fjolt.com/article/python-sets) and other data collections in Python, we can also check if something exists as a key in a dictionary. For this, we can use the `in` or `not in` operators. **Remember**, dictionaries membership is checked by key, not value.
```python
dictionary = { "name" : "Johnny", "age" : 152 }

print('name' in dictionary) # True
print('name' not in dictionary) # False
```

## Conclusion
That's everything for dictionaries - I hope you've enjoyed this Python tutorial. To learn more about engineering in general, [you can check out my other work here](https://fjolt.com). Otherwise, click the links below to learn more about the different types of data collections in Python:
- [Python Data Collections](https://fjolt.com/article/python-data-collections)
- [Python Data Collections: Lists](https://fjolt.com/article/python-lists)
- [Python Data Collections: Tuples](https://fjolt.com/article/python-tuples)
- [Python Data Collections: Sets](https://fjolt.com/article/python-sets)
- **Python Data Collections: Dictionaries**