Key Takeaways
- Understand what is a dictionary in Python and why it is one of Python's most efficient data structures for storing related data.
- Learn how dictionaries store elements as key-value pairs instead of using numeric indexes.
- Explore dictionary syntax, literals, and different ways to create dictionaries.
- Understand how key-value mapping differs from sequence indexing and why it enables fast lookups.
- Build a strong foundation before learning dictionary methods, hashing, and performance.
Introduction
"A list tells you where the data is. A dictionary tells you what the data is."
Imagine storing a student's marks. You could use a list and remember that index 0 is the name, index 1 is the age, and index 2 is the score. But as the data grows, remembering positions quickly becomes difficult and error-prone.
A dictionary in Python solves this by storing information as key-value pairs, allowing values to be retrieved using meaningful keys instead of numeric indexes. This makes dictionaries ideal for representing records, configurations, grouped data, and lookup tables. Behind this simple interface lies one of Python's fastest data structures, powered by hashing for efficient lookups. Understanding how dictionaries are organized and why their keys follow specific rules will help you write cleaner, faster, and more maintainable Python programs.
What Is a Dictionary in Python?
A dictionary in Python is a built-in data structure that stores data as key-value pairs, where each key uniquely identifies an associated value. Unlike lists or tuples, dictionary elements are accessed using keys rather than numeric indexes.
student = {
"name": "Alice",
"age": 20,
"course": "Python"
}
Here, "name", "age", and "course" are keys, while "Alice", 20, and "Python" are their corresponding values.
A dictionary is best suited for data where each value has a meaningful identifier rather than a fixed position.
Why Dictionaries Exist
Lists organize data by position. Dictionaries organize data by meaning.
Suppose you want to store information about a book.
Using a list:
book = ["Clean Code", "Robert C. Martin", 2008]
To access the author's name, you must remember that it is stored at index 1.
Using a dictionary:
book = {
"title": "Clean Code",
"author": "Robert C. Martin",
"year": 2008
}
The value can now be retrieved using a descriptive key instead of a position.
Dictionaries exist because many real-world problems involve mapping one piece of information to another, such as:
- Student ID → Student record
- Country → Capital
- Product ID → Product details
- Username → User profile
This mapping model makes dictionaries more expressive and scalable than sequences for many applications.
Dictionary vs Sequence Indexing
Lists and tuples use integer indexes to locate elements.
languages = ["Python", "Java", "C++"]
print(languages[1])
Output
Java
A dictionary uses keys instead of positions.
student = {
"name": "Alice",
"age": 20
}
print(student["name"])
Output
Alice
This difference changes how data is organized.
Sequence (List/Tuple)
Dictionary
Access by numeric index
Access by key
Position identifies data
Key identifies data
Best for ordered collections
Best for mappings and records
When the identity of the data matters more than its position, a dictionary is usually the better choice.
Creating Dictionaries in Python
Python provides multiple ways to create dictionaries. The most common approach is using dictionary literals, although the built-in dict() function can also be used.
Dictionary Syntax
The syntax of a dictionary in Python uses curly braces {} with each key mapped to a value using a colon (:). Individual key-value pairs are separated by commas.
student = {
"name": "Alice",
"age": 20,
"course": "Python"
}
General syntax:
{
key1: value1,
key2: value2,
...
}
Each key in a dictionary must be unique. If the same key appears more than once, the last assigned value replaces the previous one.
Dictionary Literals
A dictionary literal is the most direct way to create a dictionary.
Example:
car = {
"brand": "Tesla",
"model": "Model 3",
"year": 2024
}
Dictionary literals are concise, readable, and the preferred approach when the key-value pairs are known in advance.
Empty Dictionaries
An empty dictionary can be created in two ways.
Using curly braces:
student = {}
Using the dict() constructor:
student = dict()
Both create an empty dictionary that can be populated later.
student["name"] = "Alice"
student["age"] = 20
Creating an empty dictionary first is useful when data is collected dynamically, such as user input, API responses, or values generated during program execution.
Working with Dictionaries
Once a dictionary is created, you can retrieve, add, update, and remove key-value pairs. Unlike lists, dictionary operations are performed using keys rather than numeric indexes, making data easier to access and manage.
Accessing Dictionary Values
Values in a dictionary are retrieved using their corresponding keys.
student = {
"name": "Alice",
"age": 20
}
print(student["name"])
Output
Alice
If the specified key does not exist, Python raises a KeyError.
Using get()
The get() method retrieves a value without raising an error when the key is missing. Instead, it returns None or a default value if one is provided.
student = {
"name": "Alice",
"age": 20
}
print(student.get("age"))
print(student.get("course"))
Output
20
None
You can also specify a default value.
print(student.get("course", "Not Found"))
Output
Not Found
Use get() when a key may not exist and you want to avoid handling a KeyError.
Dictionary Operations
Dictionaries support common operations for managing key-value pairs.
Adding Key-Value Pairs
Assigning a value to a new key inserts a new entry into the dictionary.
student = {
"name": "Alice"
}
student["age"] = 20
print(student)
Output
{'name': 'Alice', 'age': 20}
Updating Dictionary Values
Assigning a value to an existing key replaces the previous value.
student = {
"name": "Alice",
"age": 20
}
student["age"] = 21
print(student)
Output
{'name': 'Alice', 'age': 21}
This is the most common way to update a dictionary in Python.
Removing Entries
Python provides multiple ways to remove dictionary entries.
Using del
student = {
"name": "Alice",
"age": 20
}
del student["age"]
print(student)
Output
{'name': 'Alice'}
Using pop()
The pop() method removes a key and returns its associated value.
student = {
"name": "Alice",
"age": 20
}
age = student.pop("age")
print(age)
print(student)
Output
20
{'name': 'Alice'}
Use pop() when you need both to remove an entry and preserve its value.
Dictionary Methods
Python provides several built-in dictionary methods for accessing and modifying dictionary data efficiently.
keys()
Returns a dynamic view of all dictionary keys.
student = {
"name": "Alice",
"age": 20
}
print(student.keys())
Output
dict_keys(['name', 'age'])
values()
Returns a view containing all dictionary values.
print(student.values())
Output
dict_values(['Alice', 20])
items()
Returns each key-value pair as a tuple.
print(student.items())
Output
dict_items([('name', 'Alice'), ('age', 20)])
The items() method is commonly used when both keys and values are needed during iteration.
update()
Merges another dictionary or iterable of key-value pairs into the existing dictionary.
student = {
"name": "Alice"
}
student.update({"age": 20, "course": "Python"})
print(student)
Output
{'name': 'Alice', 'age': 20, 'course': 'Python'}
If a key already exists, its value is replaced.
pop()
Removes the specified key and returns its value.
student = {
"name": "Alice",
"age": 20
}
print(student.pop("age"))
Output
20
If the key does not exist and no default value is provided, pop() raises a KeyError.
setdefault()
Returns the value for a key if it exists. Otherwise, it inserts the key with the specified default value.
student = {
"name": "Alice"
}
student.setdefault("age", 20)
print(student)
Output
{'name': 'Alice', 'age': 20}
Unlike update(), setdefault() does not overwrite an existing value.
Iterating Over Dictionaries
Iteration processes dictionary elements one key-value pair at a time. Depending on your requirement, you can iterate over keys, values, or both.
Iterating Over Keys
By default, iterating over a dictionary returns its keys.
student = {
"name": "Alice",
"age": 20
}
for key in student:
print(key)
Output
name
age
The same result can be obtained explicitly using keys().
for key in student.keys():
print(key)
Iterating Over Values
Use values() when only the stored values are required.
for value in student.values():
print(value)
Output
Alice
20
Iterating Over Key-Value Pairs
The items() method returns both the key and its associated value, making it the most efficient way to iterate over complete dictionary entries.
for key, value in student.items():
print(key, value)
Output
name Alice
age 20
When you need access to both parts of a dictionary entry, iterating with items() is clearer and more efficient than looking up each value separately using its key.
How Dictionaries Work Under the Hood
A dictionary appears to be a simple collection of key-value pairs, but internally it is designed for fast lookups, updates, and insertions. This efficiency comes from hashing, which allows Python to locate values using keys instead of searching through every element.
Why Dictionary Keys Must Be Hashable
Every dictionary key must be hashable. A hashable object has a hash value that remains unchanged during its lifetime, allowing Python to reliably locate the associated value.
Common hashable objects include:
- Strings
- Integers
- Floats
- Tuples (if all their elements are hashable)
student = {
"name": "Alice",
101: "Student ID",
(10, 20): "Coordinate"
}
Objects such as lists, dictionaries, and sets are not hashable because they are mutable.
student = {
[1, 2]: "Numbers"
}
Output
TypeError: unhashable type: 'list'
Why Immutable Keys Matter
A dictionary uses a key's hash value to determine where its corresponding value is stored. If a key could change after being inserted, its hash value would also change, making the entry difficult or impossible to locate.
This is why dictionary keys must be immutable.
For example, a string can safely be used as a key because its value cannot change after creation.
employee = {
"id": 101
}
By ensuring keys remain immutable, Python can perform consistent and reliable dictionary lookups.
How Dictionary Lookup Works
Unlike a list, a dictionary does not search entries one by one.
When you access a value, Python:
- Computes the key's hash value.
- Uses that hash to locate the corresponding storage position.
- Returns the associated value.
student = {
"name": "Alice",
"age": 20
}
print(student["name"])
Instead of checking every key sequentially, Python jumps directly to the location determined by the hash value. This is why dictionary lookups are typically much faster than searching through a list.
Insertion Order in Modern Python
Before Python 3.7, dictionaries did not guarantee that items would be returned in the order they were added.
Starting with Python 3.7, dictionaries preserve insertion order.
student = {
"name": "Alice",
"age": 20,
"course": "Python"
}
print(student)
Output
{'name': 'Alice', 'age': 20, 'course': 'Python'}
Although dictionaries preserve insertion order, they are not automatically sorted. If keys need to appear in sorted order, they must be sorted explicitly.
Dictionary Aliasing and Copying
Assigning one dictionary to another variable creates a new reference to the same dictionary, not a copy.
student = {
"name": "Alice"
}
data = student
data["age"] = 20
print(student)
Output
{'name': 'Alice', 'age': 20}
Both variables refer to the same dictionary, so changes made through one reference are visible through the other.
To create an independent dictionary, use the copy() method.
student = {
"name": "Alice"
}
data = student.copy()
data["age"] = 20
print(student)
print(data)
Output
{'name': 'Alice'}
{'name': 'Alice', 'age': 20}
The copy() method creates a shallow copy, meaning the outer dictionary is copied while nested mutable objects are still shared.
Time Complexity of Dictionary Operations
Dictionary performance comes from hash-based lookups. Most common operations complete in constant time on average, regardless of the dictionary's size.
Operation
Average Complexity
Reason
Access (dict[key])
O(1)
Hash value directly locates the entry.
Insert
O(1)
New key-value pair is placed using its hash.
Update
O(1)
Existing value is replaced using the key's hash.
Delete
O(1)
The key is located through its hash before removal.
Membership (key in dict)
O(1)
Checks whether the hashed key exists.
Iteration
O(n)
Every key-value pair is visited once.
Rather than memorizing these complexities, remember the underlying idea:
- Dictionary operations are fast because Python uses hashes instead of sequential searches.
- Lookup speed depends on keys being hashable and immutable.
- Iterating over a dictionary still requires visiting every entry, so it scales linearly with the number of items.
Dictionary Comprehensions
A dictionary comprehension creates a new dictionary by combining iteration and an optional condition into a single expression. It offers a concise alternative to building dictionaries with a loop.
Syntax
{key_expression: value_expression for item in iterable if condition}
Example:
numbers = [1, 2, 3, 4]
squares = {n: n * n for n in numbers}
print(squares)
Output
{1: 1, 2: 4, 3: 9, 4: 16}
Dictionary comprehensions are useful for transforming data, creating lookup tables, and filtering key-value pairs while keeping the code concise.
Nested Dictionaries
A nested dictionary is a dictionary whose values are themselves dictionaries. It is commonly used to model structured or hierarchical data.
students = {
"S101": {
"name": "Alice",
"marks": 92
},
"S102": {
"name": "Bob",
"marks": 88
}
}
Accessing nested values:
print(students["S101"]["marks"])
Output
92
Nested dictionary Python structures are useful for representing records, JSON data, application settings, and API responses.
Real-World Uses of Dictionaries
Because dictionaries map keys to values, they naturally model many real-world problems.
Counting Items
Dictionaries efficiently track the frequency of elements.
text = "banana"
count = {}
for ch in text:
count[ch] = count.get(ch, 0) + 1
print(count)
Grouping Data
Dictionaries can organize related values under a common key.
employees = {
"Engineering": ["Alice", "Bob"],
"Sales": ["John"]
}
Configuration Settings
Applications often store configuration values in dictionaries.
config = {
"theme": "dark",
"language": "English"
}
Dispatch Tables
A dictionary can map commands to functions, eliminating long chains of conditional statements.
operations = {
"add": add,
"subtract": subtract
}
Modeling Records
Dictionaries are widely used to represent objects with named attributes.
student = {
"name": "Alice",
"age": 20,
"course": "Python"
}
Practical Examples
Sample Dictionary
student = {
"name": "Alice",
"age": 20,
"marks": 95
}
Word Frequency Counter
sentence = "python python data"
frequency = {}
for word in sentence.split():
frequency[word] = frequency.get(word, 0) + 1
print(frequency)
Output
{'python': 2, 'data': 1}
Student Marks Lookup
marks = {
"Alice": 95,
"Bob": 88
}
print(marks["Bob"])
Output
88
These examples demonstrate how dictionaries simplify data retrieval using meaningful keys instead of numeric indexes.
Best Practices
- Use descriptive, meaningful keys.
- Keep dictionary keys immutable and hashable.
- Use get() when a key may not exist.
- Use items() when both keys and values are needed during iteration.
- Use dictionary comprehensions for simple transformations.
- Create a copy before modifying a shared dictionary.
- Choose dictionaries when data naturally forms key-value relationships.
Common Mistakes
Using Mutable Objects as Keys
Lists, dictionaries, and sets cannot be used as dictionary keys because they are not hashable.
Accessing Missing Keys Directly
student["course"]
raises a KeyError if the key doesn't exist. Use get() when the key is optional.
Confusing Assignment with Copying
a = {"name": "Alice"}
b = a
Both variables reference the same dictionary. Use copy() to create a separate dictionary.
Modifying a Dictionary While Iterating
Adding or removing entries during iteration can raise a RuntimeError. If modifications are required, iterate over a copy of the keys.
Assuming Dictionaries Are Sorted
Dictionaries preserve insertion order, but they do not sort keys automatically. Use sorted() when sorted output is required.
Summary
A dictionary in Python is a powerful mapping data structure that stores information as key-value pairs, making data retrieval fast and intuitive. In this guide, you learned how to create dictionaries, perform common dictionary operations, use built-in methods, iterate over entries, and model structured data with nested dictionaries. You also explored how hashing enables efficient lookups, why dictionary keys must be immutable and hashable, how insertion order works, and how aliasing and copying affect dictionary behavior. Understanding these concepts helps you choose dictionaries confidently and use them effectively in real-world Python programs.
Frequently Asked Questions
1. Define Dictionary in Python▾
If you need to define dictionary in Python, it can be described as:
A dictionary is a mutable mapping data structure that stores elements as unique key-value pairs.
Unlike sequences, a dictionary retrieves data using keys, making it easy to locate and update specific values.
Example:
employee = {
"id": 101,
"name": "John",
"department": "Engineering"
}Each key maps directly to a value, allowing information to be retrieved without knowing its position.
2. Are dictionaries mutable in Python?▾
Yes. Dictionaries are mutable, so entries can be added, updated, and removed after creation.
Why must dictionary keys be hashable?
Python uses the key's hash value to locate its associated value efficiently. Mutable objects cannot be used as keys because their hash values could change.
3. Is a dictionary ordered in Python?▾
Yes. Since Python 3.7, dictionaries preserve the order in which key-value pairs are inserted.
4. What is the difference between get() and direct indexing?▾
dict[key] raises a KeyError if the key is missing, whereas get() returns None or a specified default value.
5. When should I use a dictionary instead of a list?▾
Use a dictionary when data is identified by keys rather than positions, such as student records, configuration settings, or product information.


