Python Dictionaries Deep Dive
Master dictionaries – from creation and methods to comprehension, nested structures, and advanced topics. Then build a real‑world student grade manager that ties everything together.
Key‑Value Mapping
Keys must be immutable (str, int, tuple) and unique.
O(1) Lookups
Implemented with hash tables – ultra‑fast get/set.
Mutable & Flexible
Add, remove, or change key‑value pairs anytime.
Collections Module
defaultdict, Counter – built‑in power tools.
1. Creating a Dictionary
You can create a dictionary with curly braces {} or the dict() constructor. Keys must be immutable (strings, numbers, tuples) while values can be any object.
# Empty dictionary
student = {}
# With initial values
student = {
"name": "Aarav",
"grade": 8,
"subjects": ["Maths", "Science", "English"]
}
# Using dict() constructor
grades = dict(maths=95, science=88, english=92)
# Using fromkeys() – all keys get same value
names = ["Alice", "Bob", "Charlie"]
default_dict = dict.fromkeys(names, 0)
print(default_dict) # {'Alice': 0, 'Bob': 0, 'Charlie': 0}
print(student)
print(grades)
dict.fromkeys() when you need a dictionary with the same default value for all keys (e.g., counters).
2. Accessing Values
Use square brackets [] (raises KeyError if missing) or the safer .get() method.
student = {"name": "Aarav", "grade": 8, "marks": 84.5}
# Direct access (raises KeyError if key missing)
print(student["name"]) # Aarav
# Safe access with .get()
print(student.get("age")) # None
print(student.get("age", 15)) # 15 (default value)
# Set default if missing (modifies dictionary)
student.setdefault("city", "Jaipur")
print(student)
student["age"] crashes the program. Always use .get() when the key might not exist.
3. Adding and Updating Items
Assign a value to a new key to add it; assign to an existing key to update.
student = {"name": "Aarav", "grade": 8}
# Add new key
student["school"] = "XYZ Public School"
# Update existing key
student["grade"] = 9
# Bulk update using .update()
student.update({"marks": 88.5, "city": "Jaipur"})
print(student)
4. Removing Items
Several ways to delete key‑value pairs.
student = {"name": "Aarav", "grade": 8, "city": "Jaipur"}
# Delete specific key with del
del student["city"]
# Remove and return a key with .pop()
grade = student.pop("grade") # returns 8
# Remove last inserted item (Python 3.7+)
last_item = student.popitem() # returns ('name', 'Aarav')
# Clear everything
student.clear()
print(grade, last_item, student)
5. Essential Dictionary Methods
Common methods that return dynamic views or perform actions:
| Method | Description |
|---|---|
keys() | Returns a view of all keys |
values() | Returns a view of all values |
items() | Returns a view of (key, value) tuples |
get(key, default) | Returns value or default if key missing |
update(other_dict) | Merges another dictionary into the current one |
pop(key, default) | Removes key and returns its value |
popitem() | Removes and returns the last inserted pair |
setdefault(key, default) | Returns value if key exists; else sets it to default |
marks = {"maths": 95, "science": 88}
# Looping through items
for subject, score in marks.items():
print(f"{subject}: {score}")
# Getting all keys
print(list(marks.keys())) # ['maths', 'science']
# .setdefault example
marks.setdefault("english", 90) # adds because missing
marks.setdefault("maths", 0) # does nothing (key exists)
print(marks)
6. Looping Through Dictionaries
Use .keys(), .values(), or .items() for clarity and performance.
student = {"name": "Aarav", "grade": 8, "marks": 84.5}
# Loop through keys
for key in student:
print(key, "→", student[key])
# Loop through values
for val in student.values():
print(val)
# Loop through key‑value pairs (recommended)
for key, val in student.items():
print(f"{key}: {val}")
7. Nested Dictionaries
Dictionaries can contain other dictionaries – perfect for complex, hierarchical data.
class_8 = {
"Aarav": {"maths": 95, "science": 88},
"Priya": {"maths": 91, "science": 93}
}
# Access nested value
aarav_science = class_8["Aarav"]["science"] # 88
# Add new student
class_8["Rohan"] = {"maths": 76, "science": 82}
# Loop through nested dictionary
for name, marks in class_8.items():
avg = sum(marks.values()) / len(marks)
print(f"{name}: Avg = {avg:.1f}")
8. Dictionary Comprehension
A concise, Pythonic way to create or transform dictionaries in a single line. Syntax: {key_expression: value_expression for item in iterable if condition}.
# Square numbers
squares = {x: x**2 for x in range(1, 6)} # {1:1, 2:4, 3:9, 4:16, 5:25}
# Convert list to dict
words = ["apple", "banana", "cherry"]
word_len = {w: len(w) for w in words}
# Filter with comprehension
marks = {"maths": 95, "science": 88, "history": 72}
high_scores = {k: v for k, v in marks.items() if v >= 80}
# Ternary condition (if‑else inside value)
status = {num: "even" if num % 2 == 0 else "odd" for num in range(1, 6)}
print(squares)
print(word_len)
print(high_scores)
print(status)
9. Advanced Dictionary Topics
Beyond the basics: defaultdict, Counter, merging, and frequency counting.
9.1 defaultdict – Auto‑Default for Missing Keys
from collections import defaultdict
# Group words by their first letter
words = ["apple", "ant", "banana", "ball", "cherry"]
grouped = defaultdict(list)
for word in words:
grouped[word[0]].append(word)
print(dict(grouped)) # {'a': ['apple', 'ant'], 'b': ['banana', 'ball'], 'c': ['cherry']}
9.2 Counter – Counting Hashable Objects
from collections import Counter
# Count word frequencies
text = "apple banana apple orange banana apple"
word_counts = Counter(text.split())
print(word_counts) # Counter({'apple': 3, 'banana': 2, 'orange': 1})
print(word_counts["apple"]) # 3
9.3 Merging Dictionaries (Python 3.9+)
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
# Using | operator (Python 3.9+)
merged = dict1 | dict2 # {'a':1, 'b':3, 'c':4}
# Using ** unpacking (all versions)
merged_v2 = {**dict1, **dict2}
print(merged)
print(merged_v2)
🎯 Mini Project: Student Grade Manager
This project uses dictionaries, lists, tuples, sets, loops, conditionals, input validation and type casting – everything you’ve learned so far. You’ll build a complete program to manage students, store their marks, calculate averages, find toppers, and ensure data integrity.
"""
Student Grade Manager – Complete Mini Project
Concepts used: dictionaries, lists, tuples, sets, loops, conditionals,
input validation, type casting, f‑strings, and functions.
"""
def main():
students = [] # list to store dictionaries
roll_numbers = set() # set to guarantee unique roll numbers
while True:
print("\n📚 STUDENT GRADE MANAGER 📚")
print("1. Add new student")
print("2. View all students & averages")
print("3. Find class topper")
print("4. Students above class average")
print("5. Check duplicate roll numbers")
print("6. Exit")
choice = input("Choose option (1-6): ").strip()
if choice == "1":
# Input student details
name = input("Enter student name: ").strip()
try:
roll = int(input("Enter roll number: "))
if roll in roll_numbers:
print("⚠️ Roll number already exists! Duplicate not allowed.")
continue
except ValueError:
print("Roll number must be an integer.")
continue
# Grade (int)
try:
grade = int(input("Enter grade (1-12): "))
if grade < 1 or grade > 12:
print("Invalid grade. Must be 1-12.")
continue
except ValueError:
print("Invalid input. Grade must be an integer.")
continue
# Marks for 3 subjects
marks = []
subjects = ["Math", "Science", "English"]
for sub in subjects:
while True:
try:
mark = float(input(f"Enter marks for {sub} (0-100): "))
if 0 <= mark <= 100:
marks.append(mark)
break
else:
print("Marks must be between 0 and 100.")
except ValueError:
print("Please enter a valid number.")
# Store student as a dictionary
student = {
"name": name,
"roll": roll,
"grade": grade,
"marks": tuple(marks), # immutable tuple for subject marks
"total": sum(marks),
"average": sum(marks) / len(marks)
}
students.append(student)
roll_numbers.add(roll)
print(f"✅ Student {name} (Roll {roll}) added successfully!")
elif choice == "2":
if not students:
print("No students yet.")
continue
# Display all students
print("\n📊 ALL STUDENTS REPORT 📊")
print(f"{'Name':<12} {'Roll':<6} {'Grade':<6} {'Marks':<25} {'Total':<6} {'Average':<8}")
print("-" * 75)
for s in students:
marks_str = ", ".join(str(m) for m in s["marks"])
print(f"{s['name']:<12} {s['roll']:<6} {s['grade']:<6} {marks_str:<25} {s['total']:<6} {s['average']:<8.2f}")
elif choice == "3":
if not students:
print("No students yet.")
continue
# Find topper (maximum total)
topper = max(students, key=lambda x: x["total"])
print(f"🏆 Topper: {topper['name']} (Roll {topper['roll']}) with total {topper['total']} and average {topper['average']:.2f}")
elif choice == "4":
if not students:
print("No students yet.")
continue
# Calculate class average
class_avg = sum(s["average"] for s in students) / len(students)
print(f"\n📈 Class Average: {class_avg:.2f}")
print("Students scoring above class average:")
for s in students:
if s["average"] > class_avg:
print(f" - {s['name']} (Roll {s['roll']}): {s['average']:.2f}")
elif choice == "5":
# Check uniqueness of roll numbers using set
if len(roll_numbers) == len(students):
print("✅ All roll numbers are unique.")
else:
print("⚠️ Duplicate roll numbers found! (Should not happen with our validation)")
print(f"Total unique roll numbers: {len(roll_numbers)}")
print(f"Roll numbers: {sorted(roll_numbers)}")
elif choice == "6":
print("Goodbye! Keep coding 🐍")
break
else:
print("Invalid option. Please try again.")
if __name__ == "__main__":
main()
– Dictionaries store each student record with named fields.
– Tuples keep subject marks immutable.
– Sets ensure unique roll numbers.
– Loops & conditionals validate input and compute results.
– Type casting converts user input to numbers.
– List comprehension calculates class average.
– Functions structure the code.
Try extending the project: add subject‑wise toppers, sort students by average, save/load data to a file, or generate a grade letter (A/B/C) based on average.
Practice Problems (Solved)
🔰 Beginner Level
1. Word Frequency Counter
sentence = "hello world hello python world python python"
words = sentence.split()
freq = {}
for word in words:
freq[word] = freq.get(word, 0) + 1
print(freq) # {'hello': 2, 'world': 2, 'python': 3}2. Student Grade Aggregator
students = {
"Aarav": {"maths": 95, "science": 88},
"Priya": {"maths": 91, "science": 93}
}
top_student = None
highest_avg = 0
for name, marks in students.items():
avg = sum(marks.values()) / len(marks)
if avg > highest_avg:
highest_avg = avg
top_student = name
print(f"{top_student} has the highest average: {highest_avg:.1f}")⚡ Intermediate Level
3. Invert a Dictionary
original = {"a": 1, "b": 2, "c": 1}
inverted = {}
for k, v in original.items():
inverted.setdefault(v, []).append(k)
print(inverted) # {1: ['a', 'c'], 2: ['b']}4. Group Anagrams
from collections import defaultdict
words = ["eat", "tea", "tan", "ate", "nat", "bat"]
anagrams = defaultdict(list)
for word in words:
key = ''.join(sorted(word))
anagrams[key].append(word)
print(list(anagrams.values()))Unsolved Exercises
Challenge yourself – no solutions here, but you can use the solved examples and the mini project as inspiration.
🔰 Beginner Level
1. Phone Book Lookup
Create a dictionary with names and phone numbers. Ask the user for a name and print the number (or "Not found").
2. Merge Two Dictionaries
Combine dict1 and dict2 – values from dict2 overwrite dict1 if keys conflict.
⚡ Intermediate Level
3. Count Character Frequencies (case‑insensitive)
4. Find the First Non‑Repeating Character in a String
🔥 Advanced (DSA / Interview)
5. Two Sum
Given an array of integers nums and a target integer, find the indices of the two numbers that add up to target. Use a dictionary for O(n) time.
Test case: nums = [2,7,11,15], target = 9 → [0,1]
6. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. Use a dictionary to track the latest index of each character.
7. Group Anagrams from a List of Strings
Group words that are anagrams. Use defaultdict(list) with sorted word as key.