Dictionaries are also unordered container data type. It contains key-value pairs of data items. They are also called hashmap or associative arrays in other languages.

Creating Dictionary Objects

Dictionary can be created using curly braces ({}). We can also use dict() function to create a dictionary from collection of tuples. The keys and values are separated using colon (:) symbol.

1# Creating empty dictionary
2empty_dict = {}
3print(type(empty_dict)) # <class 'dict'>

We can create a dictionary with multiple key-value pairs. The key and the value should be separated using colon symbol (:).

Example:

1person = {"name": "Alex", "age": 25}
2print(person) # {'name': 'Alex', 'age': 25}

A dictionary can have integer keys or a mixed data types for the keys.

1squares = {1: 1, 
2           2: 4, 
3           3: 9, 
4           4: 16}
5print(squares) # {1: 1, 2: 4, 3: 9, 4: 16}
6
7example = {1: "one", "name": "Jacob"}
8print(example) # {1: 'one', 'name': 'Jacob'}

In Python, we can pass a container datatype with tuples containing keys and values to dict() function and create a dictionary.

1person = dict([("name", "Alex"), ("age", 25)])
2print(person) # {'name': 'Alex', 'age': 25}

Accessing Data from a Dictionary

We can access specific values from dictionary using its key. In lists, we can access data using their indices, but in dictionary, the data is unordered and do not have indices. Dictionary values are accessed using its keys.

Example:

1person = dict((("name", "Alex"), ("age", 25)))
2print(person["name"]) # Alex
3print(person["age"]) # 25

If we try to access a key which doesn’t exist, it will throw KeyError.

Example:

1person = {"name": "Alex", "age": 25}
2print(person["city"])

Output:

KeyError: 'city'

To avoid this kind of errors, we can use the get() method to get an element from the dictionary. It takes the key as argument. Optionally, it also takes the default value to return if the key was not found.

Example:

1person = {"name": "Alex", "age": 25}
2print(person.get("name")) # Alex
3print(person.get("city")) # None
4print(person.get("city", "Unknown")) # Unknown

We can add a new key-value pair or update the existing key-value pair easily by reassigning the key and values.

1person = {"name": "Alex", "age": 25}
2# add key 'city' to person dictionary
3person["city"] = "Toronto"
4print(person) # {'name': 'Alex', 'age': 25, 'city': 'Toronto'}
5# update the city for this person dictionary.
6person["city"] = "New York"
7print(person) # {'name': 'Alex', 'age': 25, 'city': 'New York'}

Dictionary Methods

Dictionary objects are one of the most used data structures in Python. Python interpreter offers many built-in methods to easily work dictionary.

To remove a key-value pair, we can use pop method on the dictionary object.

1person = {"name": "Arjun", "age": 25, "country": "India"}
2# Remove 'age' key-value pair
3person.pop("age")
4print(person) # {'name': 'Arjun', 'country': 'India'}

We could also remove any key-value pair using del operator.

1person = {"name": "Arjun", "age": 25, "country": "India"}
2del person["age"]
3print(person) # {'name': 'Arjun', 'country': 'India'}

With del operator, we can also completely remove the dictionary from system memory.

1person = {"name": "Alex", "age": 25, "country": "India"}
2del person
3print(person) # NameError: name 'person' is not defined

We can also use len() function on dictionary objects and get the number of keys in a given dictionary.

1person = {"name": "Alex", "age": 25, "country": "India"}
2print(len(person)) # 3

We could get all keys or values in the form of a dictionary using keys() and values() methods on dictionary datatype. This returns iterable which we could easily cast them to list datatype by passing them as arguments to list() function. Although the ordering is not guaranteed so adding them to two separate lists may not be that useful.

1person = {"name": "Alex", "age": 25, "country": "India"}
2print(list(person.keys())) # ['name', 'age', 'country']
3print(list(person.values())) # ['Alex', 25, 'India']

We could also set a default value for specific key in the dictionary. If the dictionary object already contains that key, it will return the value corresponding to that, but if that key doesn’t exist, when we look up for that key, it returns the default value.

Example:

1person = {"name": "Alex", "age": 25, "country": "India"}
2person.setdefault("country", "confidential")
3print(person["country"]) # India
4
5person = {"name": "Alex", "age": 25}
6person.setdefault("country", "confidential")
7print(person["country"]) # confidential

We could create a copy of a dictionary using copy() method. If we try to directly assign the variable to another variable name, Python interpreter will not actually create a copy. It will only point the new variable to the same memory location as the older dictionary object. This is also called shallow copy. This can be verified by checking the id of each object using id() function.

1person = {"name": "Alex", "age": 25}
2person2 = person
3print(id(person), id(person2)) # 1831689209024 1831689209024
4
5person3 = person.copy()
6print(id(person), id(person2)) # # 1831689209024 1831689241216

We can also clear all key-value pairs from dictionary using clear() method.

1person = {"name": "Alex", "age": 25, "country": "Canada"}
2print(person) # {'name': 'Alex', 'age': 25, 'country': 'Canada'}
3person.clear()
4print(person) # {}

Iterating through Dictionary

Dictionary objects contain key-value pairs and do not have any index, so we cannot iterate through them simply like lists or tuples. They are unordered collection of key-value pairs. But if we recall items() method, we get list of key-value tuples. This helps us iterate through all items of the dictionary.

Example:

1person = {"name": "Alex", "age": 25, "country": "Canada"}
2for item in person.items():
3    print(item)

Output:

('name', 'Alex')
('age', 25)
('country', 'Canada')

We can unpack those pairs of key-value using the tuple unpacking and get keys and values.

Example:

1person = {"name": "Alex", "age": 25, "country": "Canada"}
2for key,value in person.items():
3    print(f"{key} : {value}")

Output:

name : Alex
age : 25
country : Canada

We can also iterate over only keys using keys() method.

Example:

1person = {"name": "Alex", "age": 25, "country": "Canada"}
2
3for key in person.keys():
4    print(key)

Output:

name
age
country

For values, we can use values() method.

Example:

1person = {"name": "Alex", "age": 25, "country": "Canada"}
2
3for value in person.values():
4    print(value)

Output:

Alex
25
Canada

Dictionary Comprehension

Dictionary comprehension is similar to list comprehension but in this case, we will be creating dictionary instead of lists.

The general syntax looks like this

1{expression for elem in dictionary}

If we want to convert below numbers dictionary into its respective squares dictionary, we can do that using dictionary comprehension.

Example:

1numbers = {"one": 1, "two": 2, "three": 3, "four": 4}
2squares = {key: value * value for key, value in numbers.items()}
3print(squares) # {'one': 1, 'two': 4, 'three': 9, 'four': 16}

To swap keys with values from a dictionary, we can use below.

Example:

1numbers = {"one": 1, "two": 2, "three": 3, "four": 4}
2swapped = {value: key for key, value in numbers.items()}
3print(swapped) # {1: 'one', 2: 'two', 3: 'three', 4: 'four'}

We can also apply conditions using if clause to add only certain key-value pairs.

1numbers = {"one": 1, "two": 2, "three": 3, "four": 4}
2even_numbers = {key: value for key, value in numbers.items() if value % 2 == 0}
3print(even_numbers) # {'two': 2, 'four': 4}

We could also apply multiple conditions using multiple if clauses. We don’t need to have and operator between each if clause. It works as if it has and between each conditioanls.

1numbers = {"one": 1, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8}
2higher_evens = {key: value for key, value in numbers.items() if value > 4 if value % 2 == 0}
3print(higher_evens) # {'six': 6, 'eight': 8}