Dictionary in Python is a flexible and important data structure with several key properties and functions. Dictionary stores data in key-value pairs. It allows us to store multiple elements and manipulate data based on its keys and values.
In previous articles, we learned about other collection datatypes in Python. Lets learn about various key properties of Dictionary in Python.
Properties of Dictionary in Python
- Key-Value – Dictionary store data in key-value pairs. We can store multiple
key-value
pair elements, of different datatypes. - Unordered – Similar to Set, Dictionary is Python is also an unordered collection datatype. Dictionary elements (key-value) have no fixed order and do not maintain the sequence of its elements. From Python 3.8, dictionaries allowed to maintain the insertion order of its elements.
- Mutable – Dictionary is a mutable collection datatype. It means we can perform add (append), update (change), delete (remove) operations on the dictionary objects.
- Indexed by keys: Dictionary elements are indexed by keys. As a key-pair element, keys are indexed and values are stored for those keys (index). We can use keys to access its corresponding value.
- Immutable keys – Dictionary element keys must be unique and of immutable types (e.g., strings, numbers, and tuples). Key values can be of any datatype. Mutable datatypes like lists, sets or dictionaries cannot be used as keys.
- Dynamic size – Dictionary in Python are mutable datatype. We can perform add, update or remove operations on dictionary. Size of dictionary (number of elements in dictionary) can increase or decrease based on these operations.
- Fast lookup – Dictionary elements are key-value pair and indexed based on keys. This feature helps to provide fast searching, insertion and deletion operation within the dictionary. Because of key based indexing (hashing technique) these operations can be performed in O(1) time complexity.
- Keys, values and items iteration – Dictionary allows to traverse over all the elements. We can iterate over keys, value and items (key-value) pair of dictionaries.
- Nested Dictionary – Dictionary allows another dictionary to be stored as a value. Another dictionary cannot be used as a key.
- From Python version 3.7 and later, dictionaries maintain insertion order.
Now, lets see different methods to create Dictionary objects in Python.
Create Dictionary in Python
Dictionary in Python can be declared and initialized using either curly braces {}
or the dict()
constructor.
{}
Using curly braces Using curly braces {}
we can create an empty dictionary or a dictionary of elements.
# empty dictionary with curly brackets
print("empty dictionary creation with curly brackets")
empty_dict = {} # create an empty dictionary
print(empty_dict)
print(type(empty_dict)) # print class type of dictionary object
print("\n---------------------------------------------------\n")
# dictionary with curly brackets
print("dictionary creation with curly brackets")
training_dict = {"1": "ShBytes", "2": "Online", "3": "Training"} # create dictionary with elements
print(training_dict)
print(type(training_dict)) # print class type of dictionary object
In this program, using curly braces {}
we are creating two dictionaries. First is an empty dictionary empty_dict
and second dictionary training_dict
with key-value
pair elements. We print the elements and class type of both dictionary objects.
Program Output
empty dictionary creation with curly brackets
{} # empty dictionary represented with curly braces
<class 'dict'> # Dictionary class type is dict
---------------------------------------------------
dictionary creation with curly brackets
{'1': 'ShBytes', '2': 'Online', '3': 'Training'} # dictionary with key-value pair elements
<class 'dict'> # dictionary class type is dict
dict()
constructor
Using We can use dict()
constructor to create dictionary.
# dictionary with dict constructor
print("dictionary creation with dict constructor")
courses_dict = dict({"c1": "Python", "c2": "AWS", "c3": "Azure"}) # using dict() constructor
print(courses_dict) # print elements of courses_dict
print(type(courses_dict)) # print class type of dictionary object
using dict()
constructor we are creating a dictionary courses_dict
. This dictionary courses_dict has key-value
pair elements. We print the elements and class type of this dictionary objects.
Program Output
dictionary creation with dict constructor
{'c1': 'Python', 'c2': 'AWS', 'c3': 'Azure'} # dictionary with key-value pair elements
<class 'dict'> # dictionary class type is dict
Dictionary of Dictionaries
We can create dictionaries, where the value of a key is another dictionary. We can refer these dictionaries as nested dictionaries.
# dictionary of dictionaries
print("dictionary of dictionaries")
nested_dict = {"courses": {"c1": "Python", "c2": "AWS"}} # key courses value is another dictionary
print(nested_dict) # print elements of nested dictionary
print(type(nested_dict)) # print class type of dictionary object
Here, we have declared and initialized a nested dictionary nested_dict
. In this dictionary, value of key courses
is another dictionary.
Program Output
dictionary of dictionaries
{'courses': {'c1': 'Python', 'c2': 'AWS'}} # nested dictionary with key-value pair elements
<class 'dict'>
Dictionary key of immutable datatype
Dictionary element keys must be unique and of immutable types (e.g., strings, numbers, and tuples), but values can be of any datatype.
# dictionary key of immutable datatype
print("dictionary key of immutable datatype")
string_key_dict = {"courses": ["Python", "Java"], "numbers": (1, 2, 3)}
print(string_key_dict)
print(type(string_key_dict))
number_key_dict = {10: ["NumPy", "Pandas"], 20: {"ML", "AI"}}
print(number_key_dict)
print(type(number_key_dict))
tuple_key_dict = {(10, 20): {'Pandas', 'AI', 'NumPy', 'ML'}}
print(tuple_key_dict)
print(type(tuple_key_dict))
In this program, we have created three dictionaries with keys of immutable datatypes and values of different datatypes. All three dictionaries will be of class type dict
.
string_key_dict
with key as string and values are of list and tuple datatypenumber_key_dict
with key as number and values are of list and set datatypetuple_key_dict
with key as tuple and values are of set datatype
Program Output
dictionary key of immutable datatype
{'courses': ['Python', 'Java'], 'numbers': (1, 2, 3)}
<class 'dict'>
{10: ['NumPy', 'Pandas'], 20: {'AI', 'ML'}}
<class 'dict'>
{(10, 20): {'Pandas', 'AI', 'NumPy', 'ML'}}
<class 'dict'>
Program output shows, we can create dictionaries with key
of any immutable datatype and values are of any datatype.
Dictionary using pair
# dictionary from sequence with each item as pair
print("dictionary from sequence with each item as pair")
pair_dict = dict([(1, 'AWS'), (2, 'Python')])
print(pair_dict)
print(type(pair_dict))
In this scenario, we are using dict()
constructor with list of 2 pairs. This will create a dictionary with key as first element from pair and value as second element from pair.
Program Output
dictionary from sequence with each item as pair
{1: 'AWS', 2: 'Python'}
<class 'dict'>
zip()
Dictionary using Syntax for zip()
method – zip(*iterables)
. zip can be used to zip or unzip the elements from multiple iterable collection datatype.
# dictionary using zip
print("dictionary using zip")
zip_dict = dict(zip([1, 2, 3], ['AWS', 'Python', 'Azure']))
print(zip_dict)
print(type(zip_dict))
In this scenario, we are using built-in zip()
method and passing two lists to it. first list of number elements which will create keys
and second list of string elements which will be values
of dictionary elements.
Program Output
dictionary using zip
{1: 'AWS', 2: 'Python', 3: 'Azure'}
<class 'dict'>
Dictionary using comprehension
# dictionary using for loop
print("dictionary using for loop")
for_dict = {x: x**2 for x in (1, 2, 3)}
print(for_dict)
print(type(for_dict))
We can create dictionary using comprehension. Comprehension is useful when we need to create a dictionary from a list or another iterable.
Program Output
dictionary using for loop
{1: 1, 2: 4, 3: 9}
<class 'dict'>
Dictionary not allow duplicate keys
# dictionary does not allow duplicate keys
print("dictionary does not allow duplicate keys")
duplicate_key_dict = {1: 'AWS', 1: 'Python'}
print(duplicate_key_dict)
print(type(duplicate_key_dict))
In this case, we are creating a dictionary duplicate_key_dict
with two key-pair elements. In both value of the key is same. Dictionaries does not allow duplicate keys. The second element will replace the value of first element.
Program Output
dictionary does not allow duplicate keys
{1: 'Python'}
<class 'dict'>
Error – dictionary key of mutable datatype
Dictionary keys can only be of immutable datatype. We will get an error if dictionary key is defined with mutable datatype.
# Error - dictionary key of mutable datatype
print("Error - dictionary key of mutable datatype")
list_key_dict = {[10, 20]: {"NumPy", "Pandas", "AI", "ML"}}
print(list_key_dict)
We are creating a dictionary, with key of list datatype. List is a mutable datatype and is not allowed as a key for dictionary element.
Program Output
Error - dictionary key of mutable datatype
Traceback (most recent call last):
File "D:\create-dictionary.py", line 91, in <module>
list_key_dict = {[10, 20]: {"NumPy", "Pandas", "AI", "ML"}}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unhashable type: 'list'
Summary
In this article, we learned about various scenarios to create dictionary in Python. Following scenarios were explored:
Code – Github Repository
All code snippets and programs for this article and for Python tutorial, can be accessed from Github repository – Comments and Docstring in Python.
Python Topics
Interview Questions & Answers
Q: What is the time complexity of basic operations in a Python dictionary?
Dictionaries in Python are implemented as hash tables, which allow for average constant time insertion, deletion and search operations.
- Time complexity for Inserting, deleting and searching value in dictionary is O(1) on average.
- Time complexity for Iterating through the elements in dictionary is O(n), where n is the number of elements in the dictionary. Iterating over all key-value pairs in a dictionary involves visiting each item at-least once.
Q: How Python handles collision in dictionaries?
Collision of dictionaries means two keys hash are same and they point to the same index.
- Python handles collisions using open addressing with probing. It means, when a collision occurs between key-value pairs of dictionary, Python look for the next available slot according to a defined probing sequence.
- If many collisions occur, the time complexity for insertion, deletion, or lookup can degrade from O(1) to O(n) in the worst case. Python hash tables are designed to avoid these collision scenarios and minimize the risk of performance degradation.
Q: Describe a real-world use case for Python dictionary?
Most common use case for dictionaries is to implement caching for a web application. Dictionary would be ideal for storing cached responses from an API or database. The keys could be the request parameters (e.g., a URL or query) and the values could be the corresponding responses. Because dictionaries offer O(1) average-time complexity for lookup, this allows very fast retrieval of cached data, significantly improving the performance of the application.
Q: What are the limitations of using dictionaries in Python?
- Memory Intensive – Python dictionaries are memory-intensive because they maintain a large amount of data in memory to ensure fast operations. This creates problems in memory-constrained environments.
- Unordered – Dictionaries are inherently unordered data structure, but since Python 3.7 dictionaries maintain insertion order. Additional logic is required to maintain order based on the values or some other criteria.
- Hashable keys – Keys in a Python dictionary must be hash-able, which means mutable types like lists cannot be used as keys. This limits the flexibility of the data structure when dealing with certain types of data.
Q: With the large dataset, how would you decide which data structure to use like lists or sets or dictionary?
- Use dictionary when we need to associate unique keys with specific values, and require fast lookup, insertions, and deletions by key.
- Use list when we need an ordered collection of items that will primarily be accessed by index, and where fast insertions, deletions, and lookup by position are important.
- Use set when we need to store unique items, require fast membership testing, and do not need to associate each item with a specific value. Sets are also useful when performing mathematical set operations like union, intersection, and difference.