1. What are Dictionaries? The Basics
A dictionary is an unordered (pre-Python 3.7) or insertion-ordered (Python 3.7+), mutable collection of items. Each item is a key-value pair.
-
Keys: Must be unique and immutable. Common key types are strings, numbers (integers, floats), and tuples. Lists cannot be keys.
-
Values: Can be anything (strings, numbers, lists, other dictionaries, etc.). Values do not have to be unique.
-
Mutable: You can add, remove, and modify key-value pairs after a dictionary is created.
-
Insertion-Ordered (Python 3.7+): While historically unordered, modern Python guarantees that dictionary items retain the order in which they were added.
Syntax: Dictionaries are created using curly braces `{}`, with key-value pairs separated by colons, and pairs separated by commas.
# An empty dictionary
empty_dict = {}
# Dictionary with string keys (UdaanPath profile)
user_profile = {
"name": "Alice",
"age": 30,
"city": "New York",
"is_active": True
}
# Dictionary with mixed key types (less common but possible)
mixed_keys = {
"status_code": 200,
1: "success",
(1, 2): "coordinates" # A tuple as a key (tuples are immutable!)
}
# Dictionary with list as a value
student_grades = {
"John": [90, 85, 92],
"Jane": [78, 88, 95]
}
print(f"Empty dict: {empty_dict}")
print(f"User Profile: {user_profile}")
print(f"Mixed Keys: {mixed_keys}")
print(f"Student Grades: {student_grades}")
print(f"Type of 'user_profile': {type(user_profile)}")
Empty dict: {}
User Profile: {'name': 'Alice', 'age': 30, 'city': 'New York', 'is_active': True}
Mixed Keys: {'status_code': 200, 1: 'success', (1, 2): 'coordinates'}
Student Grades: {'John': [90, 85, 92], 'Jane': [78, 88, 95]}
Type of 'user_profile': <class 'dict'>
2. Accessing Dictionary Elements
You access values in a dictionary using their corresponding keys, not numerical indices.
-
Using Square Brackets `dict[key]` (Direct Access): This is the most common way. If the key does not exist, it will raise a
KeyError.
-
Using `.get(key, default_value)` (Safer Access): This method returns the value for the specified key. If the key is not found, it returns `None` by default, or the `default_value` you provide. This prevents `KeyError`s.
person = {
"name": "Bob",
"age": 40,
"occupation": "Engineer"
}
print(f"Person's name (direct access): {person['name']}")
print(f"Person's age (direct access): {person['age']}")
# Accessing a non-existent key (will cause error)
try:
print(f"Email: {person['email']}")
except KeyError as e:
print(f"Error accessing non-existent key: {e}")
# Using .get() - safer access
print(f"Person's occupation (using .get()): {person.get('occupation')}")
print(f"Person's email (using .get() with default None): {person.get('email')}")
print(f"Person's phone (using .get() with custom default): {person.get('phone', 'N/A')}")
Person's name (direct access): Bob
Person's age (direct access): 40
Error accessing non-existent key: 'email'
Person's occupation (using .get()): Engineer
Person's email (using .get() with default None): None
Person's phone (using .get() with custom default): N/A
3. Modifying Dictionaries: Adding and Updating
Dictionaries are mutable, allowing you to easily add new key-value pairs or change existing values.
Adding New Key-Value Pairs:
Simply assign a value to a new key.
student_info = {"id": 101, "name": "Geeta"}
print(f"Initial student_info: {student_info}")
student_info["course"] = "Python for Data Science" # Add new key-value pair
student_info["gpa"] = 3.8
print(f"After adding course and GPA: {student_info}")
Initial student_info: {'id': 101, 'name': 'Geeta'}
After adding course and GPA: {'id': 101, 'name': 'Geeta', 'course': 'Python for Data Science', 'gpa': 3.8}
Updating Existing Values:
Assign a new value to an existing key.
product = {"name": "Laptop", "price": 1200}
print(f"Initial product: {product}")
product["price"] = 1150 # Update the price
product["name"] = "Lightweight Laptop" # Update the name
print(f"After updates: {product}")
Initial product: {'name': 'Laptop', 'price': 1200}
After updates: {'name': 'Lightweight Laptop', 'price': 1150}
Merging Dictionaries with .update():
The `update()` method allows you to merge another dictionary or an iterable of key-value pairs into the current dictionary. If keys exist, their values are updated; otherwise, new pairs are added.
user_data = {"id": 1, "name": "Udaan", "status": "active"}
new_info = {"status": "suspended", "last_login": "2025-07-22"}
print(f"Initial user_data: {user_data}")
user_data.update(new_info)
print(f"After update: {user_data}")
Initial user_data: {'id': 1, 'name': 'Udaan', 'status': 'active'}
After update: {'id': 1, 'name': 'Udaan', 'status': 'suspended', 'last_login': '2025-07-22'}
4. Removing Elements from Dictionaries
-
del dict[key]: Deletes the key-value pair associated with the specified key. Raises `KeyError` if the key doesn't exist.
-
.pop(key, [default]): Removes the item with the specified key and returns its value. If the key is not found, it returns the `default` value (if provided), otherwise it raises a `KeyError`.
-
.popitem(): Removes and returns an arbitrary key-value pair. In Python 3.7+, it removes and returns the last inserted key-value pair. Raises `KeyError` if the dictionary is empty.
-
.clear(): Removes all key-value pairs from the dictionary, making it empty.
config = {"theme": "dark", "notifications": True, "language": "en"}
print(f"Initial config: {config}")
del config["notifications"] # Delete by key
print(f"After del 'notifications': {config}")
# Using pop()
removed_lang = config.pop("language")
print(f"After pop 'language': {config}, Removed: {removed_lang}")
# Using pop() with a default for non-existent key
removed_option = config.pop("font_size", "Not found")
print(f"Attempt pop 'font_size': {config}, Result: {removed_option}")
# Using popitem()
last_item = config.popitem() # Removes ('theme', 'dark') in this case
print(f"After popitem(): {config}, Last item: {last_item}")
my_empty_dict = {"a": 1, "b": 2}
my_empty_dict.clear()
print(f"After clear: {my_empty_dict}")
Initial config: {'theme': 'dark', 'notifications': True, 'language': 'en'}
After del 'notifications': {'theme': 'dark', 'language': 'en'}
After pop 'language': {'theme': 'dark'}, Removed: en
Attempt pop 'font_size': {'theme': 'dark'}, Result: Not found
After popitem(): {}, Last item: ('theme', 'dark')
After clear: {}
Interview Tip: Understand when to use `del`, `.pop()`, and `.get()` for access and removal. `get()` is preferred for accessing potentially non-existent keys to avoid errors. `pop()` is great when you need the value you're removing.
5. Dictionary View Objects and Operators
Dictionaries provide "view objects" that reflect the current state of the dictionary's keys, values, or items. These views are dynamic.
-
len(dict): (Built-in function) Returns the number of key-value pairs.
-
dict.keys(): Returns a view object that displays a list of all the keys.
-
dict.values(): Returns a view object that displays a list of all the values.
-
dict.items(): Returns a view object that displays a list of a dictionary's key-value tuple pairs.
-
`key in dict` operator: Checks if a key exists in the dictionary. Returns `True` or `False`.
city_data = {
"name": "Mumbai",
"population": 20_000_000,
"country": "India"
}
print(f"Number of key-value pairs: {len(city_data)}")
print(f"All keys: {city_data.keys()}")
print(f"All values: {city_data.values()}")
print(f"All items: {city_data.items()}")
print(f"'name' in city_data: {'name' in city_data}")
print(f"'area' in city_data: {'area' in city_data}")
print(f"'Mumbai' in city_data values: {'Mumbai' in city_data.values()}") # Checks values, not keys
Number of key-value pairs: 3
All keys: dict_keys(['name', 'population', 'country'])
All values: dict_values(['Mumbai', 20000000, 'India'])
All items: dict_items([('name', 'Mumbai'), ('population', 20000000), ('country', 'India')])
'name' in city_data: True
'area' in city_data: False
'Mumbai' in city_data values: True
6. Iterating Over Dictionaries: The Power of Loops
Combining dictionaries with `for` loops is incredibly powerful for processing structured data.
-
Iterating through Keys (Default): When you loop directly over a dictionary, you get its keys.
-
Iterating through Values: Use `.values()` method.
-
Iterating through Items (Keys and Values): Use `.items()` method, which yields key-value pairs as tuples that can be unpacked directly in the `for` loop. This is the most common way to iterate through both.
Example: UdaanPath Course Details
course_details = {
"title": "Advanced Python",
"duration": "8 weeks",
"instructor": "Dr. Sharma",
"price": 499.99
}
print("Course Details (Iterating over keys):")
for key in course_details: # Default iteration gives keys
print(f"{key}: {course_details[key]}") # Access value using the key
print("\nCourse Details (Iterating over values):")
for value in course_details.values():
print(f"Value: {value}")
print("\nCourse Details (Iterating over items - key-value pairs):")
for key, value in course_details.items(): # Unpacking key and value
print(f"Key: {key}, Value: {value}")
Course Details (Iterating over keys):
title: Advanced Python
duration: 8 weeks
instructor: Dr. Sharma
price: 499.99
Course Details (Iterating over values):
Value: Advanced Python
Value: 8 weeks
Value: Dr. Sharma
Value: 499.99
Course Details (Iterating over items - key-value pairs):
Key: title, Value: Advanced Python
Key: duration, Value: 8 weeks
Key: instructor, Value: Dr. Sharma
Key: price, Value: 499.99