Python Dictionary Complete Guide
Learn all Python dictionary operations - creation, manipulation, built-in methods, comprehension, and advanced operations with practical examples.
Key-Value
Pairs storage
Fast Lookup
O(1) access
Mutable
Can be modified
Unordered
Python 3.7+ ordered
What are Python Dictionaries?
Dictionaries in Python are unordered (Python 3.6 and earlier) or ordered (Python 3.7+) collections of key-value pairs. They are mutable, fast for lookups, and keys must be immutable (strings, numbers, tuples).
Key Concept
Python dictionaries are hash tables that provide O(1) average time complexity for lookups. Keys must be hashable (immutable), while values can be any Python object.
# Creating dictionaries
empty_dict = {}
person = {"name": "Alice", "age": 30, "city": "New York"}
# Using dict() constructor
person2 = dict(name="Bob", age=25, city="London")
person3 = dict([("name", "Charlie"), ("age", 35), ("city", "Paris")])
# Dictionary with different key types
mixed_keys = {
"string_key": "value1",
123: "value2", # integer key
(1, 2): "value3", # tuple key (immutable)
# [1, 2]: "value4" # ERROR: list is mutable, not hashable
}
# Accessing values
print(person["name"]) # "Alice" - using key
print(person.get("age")) # 30 - using get() method
print(person.get("email", "Not found")) # "Not found" - default value
# Modifying dictionaries
person["age"] = 31 # Update existing key
person["email"] = "alice@example.com" # Add new key-value pair
# Dictionary length
print(f"Length: {len(person)}") # 4
# Checking key existence
print("name" in person) # True
print("phone" in person) # False
print("phone" not in person) # True
# Deleting items
del person["city"] # Remove key-value pair
removed_value = person.pop("age") # Remove and return value
person.popitem() # Remove and return last item (Python 3.7+)
person.clear() # Remove all items
# Dictionary iteration
person = {"name": "Alice", "age": 30, "city": "New York"}
# Iterate through keys (default)
for key in person:
print(f"Key: {key}, Value: {person[key]}")
# Iterate through key-value pairs
for key, value in person.items():
print(f"{key}: {value}")
# Iterate through values
for value in person.values():
print(f"Value: {value}")
# Iterate through keys
for key in person.keys():
print(f"Key: {key}")
Python Dictionary Methods Complete Reference
Python provides powerful built-in dictionary methods for various operations. Here's a comprehensive table of all dictionary methods with examples.
Complete Dictionary Methods Reference Table
| Category | Method | Description | Syntax Example | Result |
|---|---|---|---|---|
| Access Methods | get() | Returns value for key, or default if key doesn't exist | dict.get("key", "default") |
value or "default" |
| Access Methods | setdefault() | Returns value if key exists, else inserts key with default | dict.setdefault("key", "default") |
value or sets "default" |
| View Methods | keys() | Returns view of all keys | dict.keys() |
dict_keys(['key1', 'key2']) |
| View Methods | values() | Returns view of all values | dict.values() |
dict_values(['val1', 'val2']) |
| View Methods | items() | Returns view of all (key, value) pairs | dict.items() |
dict_items([('key1','val1'),...]) |
| Modification | pop() | Removes key and returns its value | dict.pop("key") |
removed value |
| Modification | popitem() | Removes and returns last (key, value) pair | dict.popitem() |
(key, value) |
| Modification | clear() | Removes all items from dictionary | dict.clear() |
{} |
| Update Methods | update() | Updates dictionary with key-value pairs from another | dict.update(other_dict) |
merged dictionary |
| Copy Methods | copy() | Returns shallow copy of dictionary | dict.copy() |
new dictionary copy |
| Utility | fromkeys() | Creates new dictionary with keys from iterable and value | dict.fromkeys(keys, value) |
new dictionary |
dict[key]vsdict.get(key): bracket notation raises KeyError if key doesn't exist, get() returns None or defaultdict.keys(),dict.values(),dict.items()return dynamic views that reflect dictionary changesdict.update()merges dictionaries, overwriting existing keys with new valuesdict.setdefault()is useful for initializing dictionary valuesdict.copy()creates shallow copy; usecopy.deepcopy()for nested dictionaries
Dictionary Methods Practical Examples
See dictionary methods in action with practical examples and real-world use cases.
# get() method - safe access
person = {"name": "Alice", "age": 30}
print(person.get("name")) # "Alice"
print(person.get("email")) # None (key doesn't exist)
print(person.get("email", "N/A")) # "N/A" (with default value)
# Compare with bracket notation
try:
print(person["email"]) # KeyError!
except KeyError as e:
print(f"KeyError: {e}")
# setdefault() - get or set with default
person = {"name": "Alice", "age": 30}
# Key exists - returns value
city = person.setdefault("city", "Unknown")
print(f"City: {city}, Person: {person}") # City: Unknown, Person now has city
# Key exists - returns existing value
name = person.setdefault("name", "Bob")
print(f"Name: {name}") # Name: Alice (doesn't change existing)
# keys(), values(), items() views
person = {"name": "Alice", "age": 30, "city": "NYC"}
keys_view = person.keys()
values_view = person.values()
items_view = person.items()
print(f"Keys: {keys_view}") # dict_keys(['name', 'age', 'city'])
print(f"Values: {values_view}") # dict_values(['Alice', 30, 'NYC'])
print(f"Items: {items_view}") # dict_items([('name', 'Alice'), ...])
# Views are dynamic
person["email"] = "alice@example.com"
print(f"Keys after update: {keys_view}") # Now includes 'email'
# Convert views to lists
keys_list = list(person.keys())
print(f"Keys as list: {keys_list}")
# pop() - remove and return value
person = {"name": "Alice", "age": 30, "city": "NYC"}
age = person.pop("age")
print(f"Removed age: {age}, Person: {person}")
# pop() with default
email = person.pop("email", "not found")
print(f"Email: {email}") # "not found" (key didn't exist)
# popitem() - remove and return last item (Python 3.7+)
person = {"name": "Alice", "age": 30, "city": "NYC"}
last_item = person.popitem()
print(f"Removed: {last_item}, Person: {person}")
# clear() - remove all items
person.clear()
print(f"After clear: {person}") # {}
# update() - merge dictionaries
person = {"name": "Alice", "age": 30}
additional_info = {"city": "NYC", "email": "alice@example.com"}
person.update(additional_info)
print(f"After update: {person}") # {'name': 'Alice', 'age': 30, 'city': 'NYC', 'email': 'alice@example.com'}
# update() with overwriting
person.update({"age": 31, "city": "Boston"})
print(f"After overwriting update: {person}") # age and city updated
# update() with multiple formats
person.update([("country", "USA"), ("zip", "10001")])
person.update(state="NY", phone="123-456-7890")
print(f"After multiple updates: {person}")
# copy() - create shallow copy
original = {"name": "Alice", "scores": [85, 90, 78]}
copied = original.copy()
original["name"] = "Bob"
original["scores"].append(95)
print(f"Original: {original}") # {'name': 'Bob', 'scores': [85, 90, 78, 95]}
print(f"Copied: {copied}") # {'name': 'Alice', 'scores': [85, 90, 78, 95]} (nested list shared!)
# fromkeys() - create dictionary with default value
keys = ["name", "age", "city"]
default_dict = dict.fromkeys(keys)
print(f"Default dict: {default_dict}") # {'name': None, 'age': None, 'city': None}
default_dict = dict.fromkeys(keys, "unknown")
print(f"Dict with 'unknown': {default_dict}") # {'name': 'unknown', 'age': 'unknown', 'city': 'unknown'}
# Dictionary comprehensions
numbers = [1, 2, 3, 4, 5]
squares = {x: x**2 for x in numbers}
print(f"Squares dict: {squares}") # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Conditional dictionary comprehension
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(f"Even squares: {even_squares}") # {2: 4, 4: 16}
# Transform existing dictionary
person = {"name": "alice", "age": "30", "city": "nyc"}
uppercase = {k: v.upper() if isinstance(v, str) else v for k, v in person.items()}
print(f"Uppercase values: {uppercase}") # {'name': 'ALICE', 'age': '30', 'city': 'NYC'}
Dictionary Operations & Techniques
Learn advanced dictionary operations including merging, nesting, and various manipulation techniques.
# Dictionary merging (Python 3.5+)
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4} # Note: 'b' exists in both
# Method 1: update() (modifies dict1)
dict1.update(dict2)
print(f"After update: {dict1}") # {'a': 1, 'b': 3, 'c': 4} (dict2's 'b' wins)
# Method 2: {**dict1, **dict2} (creates new dict)
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged = {**dict1, **dict2}
print(f"Merged: {merged}") # {'a': 1, 'b': 3, 'c': 4}
# Method 3: | operator (Python 3.9+)
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged = dict1 | dict2
print(f"Merged with |: {merged}") # {'a': 1, 'b': 3, 'c': 4}
# In-place merge with |= (Python 3.9+)
dict1 |= dict2
print(f"dict1 after |=: {dict1}") # {'a': 1, 'b': 3, 'c': 4}
# Dictionary comprehension with multiple sources
keys = ["a", "b", "c"]
values = [1, 2, 3]
dict_from_lists = {k: v for k, v in zip(keys, values)}
print(f"Dict from lists: {dict_from_lists}") # {'a': 1, 'b': 2, 'c': 3}
# Swapping keys and values (if values are hashable)
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(f"Swapped: {swapped}") # {1: 'a', 2: 'b', 3: 'c'}
# Filtering dictionaries
student_scores = {"Alice": 85, "Bob": 72, "Charlie": 90, "David": 68, "Eve": 95}
# Filter students with score >= 80
top_students = {name: score for name, score in student_scores.items() if score >= 80}
print(f"Top students: {top_students}") # {'Alice': 85, 'Charlie': 90, 'Eve': 95}
# Sort dictionary by keys
sorted_by_key = dict(sorted(student_scores.items()))
print(f"Sorted by key: {sorted_by_key}")
# Sort dictionary by values
sorted_by_value = dict(sorted(student_scores.items(), key=lambda item: item[1]))
print(f"Sorted by value: {sorted_by_value}")
# Sort by value descending
sorted_desc = dict(sorted(student_scores.items(), key=lambda item: item[1], reverse=True))
print(f"Sorted by value descending: {sorted_desc}")
# Dictionary unpacking
def print_person(name, age, city):
print(f"{name} is {age} years old and lives in {city}")
person = {"name": "Alice", "age": 30, "city": "NYC"}
print_person(**person) # Unpacks dictionary as keyword arguments
# Default values with get() for counting
text = "hello world hello python world python python"
word_count = {}
for word in text.split():
word_count[word] = word_count.get(word, 0) + 1
print(f"Word count: {word_count}") # {'hello': 2, 'world': 2, 'python': 3}
# Using defaultdict for counting
from collections import defaultdict
word_count = defaultdict(int)
for word in text.split():
word_count[word] += 1
print(f"Word count with defaultdict: {dict(word_count)}")
# Grouping with dictionary
people = [
{"name": "Alice", "city": "NYC"},
{"name": "Bob", "city": "London"},
{"name": "Charlie", "city": "NYC"},
{"name": "David", "city": "Paris"},
{"name": "Eve", "city": "London"}
]
# Group by city
city_groups = {}
for person in people:
city = person["city"]
if city not in city_groups:
city_groups[city] = []
city_groups[city].append(person["name"])
print(f"Grouped by city: {city_groups}")
# {'NYC': ['Alice', 'Charlie'], 'London': ['Bob', 'Eve'], 'Paris': ['David']}
# Using setdefault() for grouping
city_groups = {}
for person in people:
city_groups.setdefault(person["city"], []).append(person["name"])
print(f"Grouped with setdefault: {city_groups}")
# Dictionary as switch/case replacement
def operation_add(a, b):
return a + b
def operation_subtract(a, b):
return a - b
def operation_multiply(a, b):
return a * b
def operation_divide(a, b):
return a / b if b != 0 else "Cannot divide by zero"
operations = {
"add": operation_add,
"subtract": operation_subtract,
"multiply": operation_multiply,
"divide": operation_divide
}
# Use like a switch statement
op = "multiply"
result = operations[op](10, 5)
print(f"10 {op} 5 = {result}") # 10 multiply 5 = 50
Working with Nested Dictionaries
Nested dictionaries (dictionaries within dictionaries) are common in Python for representing complex, hierarchical data structures.
# Creating nested dictionaries
company = {
"name": "TechCorp",
"departments": {
"engineering": {
"manager": "Alice",
"employees": 50,
"projects": ["Project A", "Project B"]
},
"sales": {
"manager": "Bob",
"employees": 30,
"regions": ["North", "South", "East", "West"]
},
"hr": {
"manager": "Charlie",
"employees": 10
}
},
"location": "Silicon Valley"
}
# Accessing nested values
print(f"Company: {company['name']}")
print(f"Engineering manager: {company['departments']['engineering']['manager']}")
print(f"Sales regions: {company['departments']['sales']['regions']}")
# Safe access with get() in nested dictionaries
print(f"Engineering projects: {company.get('departments', {}).get('engineering', {}).get('projects', 'No projects')}")
# Modifying nested dictionaries
# Add new department
company["departments"]["marketing"] = {
"manager": "David",
"employees": 15,
"budget": 100000
}
# Update existing department
company["departments"]["engineering"]["employees"] = 55
company["departments"]["engineering"]["projects"].append("Project C")
# Iterating through nested dictionaries
print("\nCompany Structure:")
for dept_name, dept_info in company["departments"].items():
print(f"\nDepartment: {dept_name}")
for key, value in dept_info.items():
print(f" {key}: {value}")
# Flatten nested dictionary
def flatten_dict(d, parent_key='', sep='.'):
items = []
for k, v in d.items():
new_key = f"{parent_key}{sep}{k}" if parent_key else k
if isinstance(v, dict):
items.extend(flatten_dict(v, new_key, sep=sep).items())
else:
items.append((new_key, v))
return dict(items)
flat_company = flatten_dict(company)
print(f"\nFlattened company structure: {flat_company}")
# More complex nested structure
university = {
"name": "State University",
"colleges": {
"engineering": {
"departments": {
"cs": {
"head": "Dr. Smith",
"courses": ["CS101", "CS201", "CS301"],
"students": 300
},
"ee": {
"head": "Dr. Johnson",
"courses": ["EE101", "EE201"],
"students": 200
}
},
"dean": "Dr. Brown"
},
"arts": {
"departments": {
"english": {
"head": "Dr. Williams",
"courses": ["ENG101", "ENG201"],
"students": 150
}
},
"dean": "Dr. Davis"
}
}
}
# Deep access with error handling
try:
cs_courses = university["colleges"]["engineering"]["departments"]["cs"]["courses"]
print(f"\nCS Courses: {cs_courses}")
except KeyError as e:
print(f"Key not found: {e}")
# Using get() with default for deep access
cs_students = university.get("colleges", {}).get("engineering", {}).get("departments", {}).get("cs", {}).get("students", 0)
print(f"CS Students: {cs_students}")
# Recursive function to find all values for a key
def find_all_values(data, target_key):
results = []
if isinstance(data, dict):
for key, value in data.items():
if key == target_key:
results.append(value)
elif isinstance(value, (dict, list)):
results.extend(find_all_values(value, target_key))
elif isinstance(data, list):
for item in data:
results.extend(find_all_values(item, target_key))
return results
all_heads = find_all_values(university, "head")
print(f"All department heads: {all_heads}")
# Dictionary of dictionaries (2D structure)
student_grades = {
"Alice": {"math": 85, "science": 90, "history": 78},
"Bob": {"math": 72, "science": 88, "history": 85},
"Charlie": {"math": 95, "science": 92, "history": 88}
}
# Calculate average for each student
print("\nStudent Averages:")
for student, grades in student_grades.items():
average = sum(grades.values()) / len(grades)
print(f"{student}: {average:.2f}")
# Find student with highest math score
best_math = max(student_grades.items(), key=lambda x: x[1]["math"])
print(f"\nBest math score: {best_math[0]} with {best_math[1]['math']}")
# Add new student
student_grades["David"] = {"math": 80, "science": 85, "history": 75}
# Update grade for existing student
student_grades["Alice"]["math"] = 88
# Add new subject for all students
new_subject = "english"
for student in student_grades:
student_grades[student][new_subject] = 85 # Default grade
print(f"\nUpdated student grades with English: {student_grades}")
Dictionary Comprehension
Dictionary comprehension provides a concise way to create dictionaries. It's similar to list comprehension but produces dictionaries.
# Basic dictionary comprehension
# {key_expression: value_expression for item in iterable}
# Create dictionary of squares
numbers = [1, 2, 3, 4, 5]
squares = {x: x**2 for x in numbers}
print(f"Squares: {squares}") # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# With condition
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(f"Even squares: {even_squares}") # {2: 4, 4: 16}
# Transform existing dictionary
student_scores = {"Alice": 85, "Bob": 72, "Charlie": 90, "David": 68}
# Add bonus points
bonus_scores = {name: score + 5 for name, score in student_scores.items()}
print(f"With bonus: {bonus_scores}") # {'Alice': 90, 'Bob': 77, 'Charlie': 95, 'David': 73}
# Filter and transform
passing_students = {name: score for name, score in student_scores.items() if score >= 70}
print(f"Passing students: {passing_students}") # {'Alice': 85, 'Bob': 72, 'Charlie': 90}
# Switch keys and values (if values are unique and hashable)
swapped = {score: name for name, score in student_scores.items()}
print(f"Swapped: {swapped}") # {85: 'Alice', 72: 'Bob', 90: 'Charlie', 68: 'David'}
# Multiple iterables with zip
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
name_age_dict = {name: age for name, age in zip(names, ages)}
print(f"Name-age dictionary: {name_age_dict}") # {'Alice': 25, 'Bob': 30, 'Charlie': 35}
# Nested dictionary comprehension
# Create multiplication table
multiplication_table = {i: {j: i*j for j in range(1, 6)} for i in range(1, 6)}
print("\nMultiplication table (1-5):")
for i, row in multiplication_table.items():
print(f"{i}: {row}")
# Conditional key/value expressions
numbers = [1, 2, 3, 4, 5]
result = {x: "even" if x % 2 == 0 else "odd" for x in numbers}
print(f"Even/odd mapping: {result}") # {1: 'odd', 2: 'even', 3: 'odd', 4: 'even', 5: 'odd'}
# Flatten nested dictionary using comprehension
nested_dict = {
"a": {"x": 1, "y": 2},
"b": {"z": 3},
"c": {"w": 4, "v": 5}
}
flattened = {f"{outer_key}.{inner_key}": value
for outer_key, inner_dict in nested_dict.items()
for inner_key, value in inner_dict.items()}
print(f"Flattened: {flattened}") # {'a.x': 1, 'a.y': 2, 'b.z': 3, 'c.w': 4, 'c.v': 5}
# Dictionary comprehension with enumerate
words = ["apple", "banana", "cherry", "date"]
word_lengths = {word: len(word) for word in words}
print(f"Word lengths: {word_lengths}") # {'apple': 5, 'banana': 6, 'cherry': 6, 'date': 4}
# With index as key
indexed_words = {i: word for i, word in enumerate(words)}
print(f"Indexed words: {indexed_words}") # {0: 'apple', 1: 'banana', 2: 'cherry', 3: 'date'}
# Complex transformation
students = [
{"name": "Alice", "scores": [85, 90, 78]},
{"name": "Bob", "scores": [72, 88, 85]},
{"name": "Charlie", "scores": [95, 92, 88]}
]
# Create dictionary of average scores
average_scores = {
student["name"]: sum(student["scores"]) / len(student["scores"])
for student in students
}
print(f"Average scores: {average_scores}") # {'Alice': 84.33, 'Bob': 81.67, 'Charlie': 91.67}
# Dictionary comprehension with if-else in key/value
temperatures = {"NYC": 30, "London": 15, "Mumbai": 35, "Tokyo": 25}
temperature_status = {
city: ("Hot" if temp > 30 else "Warm" if temp > 20 else "Cool")
for city, temp in temperatures.items()
}
print(f"Temperature status: {temperature_status}")
# {'NYC': 'Warm', 'London': 'Cool', 'Mumbai': 'Hot', 'Tokyo': 'Warm'}
# Merge multiple dictionaries with comprehension
dicts = [
{"a": 1, "b": 2},
{"b": 3, "c": 4},
{"d": 5}
]
# Last dict wins for duplicate keys
merged = {k: v for d in dicts for k, v in d.items()}
print(f"Merged dictionaries: {merged}") # {'a': 1, 'b': 3, 'c': 4, 'd': 5}
Dictionary Practice Exercises
Try these exercises to test your understanding of Python dictionaries.
# Python Dictionaries Practice Exercises
print("=== Exercise 1: Basic Dictionary Operations ===")
# 1. Create a dictionary of 5 countries and their capitals
capitals = {
"USA": "Washington D.C.",
"UK": "London",
"France": "Paris",
"Germany": "Berlin",
"Japan": "Tokyo"
}
print(f"Capitals: {capitals}")
# 2. Add a new country-capital pair
capitals["India"] = "New Delhi"
print(f"After adding India: {capitals}")
# 3. Update an existing capital
capitals["USA"] = "Washington"
print(f"After updating USA: {capitals}")
print("\n=== Exercise 2: Dictionary Manipulation ===")
# 4. Count word frequency in a text
text = "apple banana apple orange banana apple mango"
words = text.split()
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
print(f"Word frequencies: {word_count}")
# 5. Find the most common word
most_common = max(word_count, key=word_count.get)
print(f"Most common word: '{most_common}' with {word_count[most_common]} occurrences")
print("\n=== Exercise 3: Dictionary Comprehension ===")
# 6. Create dictionary of cubes for numbers 1-10
cubes = {x: x**3 for x in range(1, 11)}
print(f"Cubes 1-10: {cubes}")
# 7. Filter dictionary to include only even cubes
even_cubes = {x: cube for x, cube in cubes.items() if cube % 2 == 0}
print(f"Even cubes: {even_cubes}")
print("\n=== Exercise 4: Nested Dictionaries ===")
# 8. Create student records dictionary
students = {
1001: {"name": "Alice", "age": 20, "grades": {"math": 85, "science": 90}},
1002: {"name": "Bob", "age": 21, "grades": {"math": 78, "science": 88}},
1003: {"name": "Charlie", "age": 19, "grades": {"math": 92, "science": 95}}
}
# Add a new student
students[1004] = {"name": "David", "age": 22, "grades": {"math": 80, "science": 85}}
# Calculate average grade for each student
print("Student averages:")
for student_id, info in students.items():
grades = info["grades"].values()
average = sum(grades) / len(grades)
print(f"{info['name']}: {average:.2f}")
print("\n=== Exercise 5: Advanced Operations ===")
# 9. Merge two dictionaries with custom conflict resolution
dict1 = {"a": 1, "b": 2, "c": 3}
dict2 = {"b": 20, "c": 30, "d": 40}
# Merge with sum for common keys
merged = dict1.copy()
for key, value in dict2.items():
if key in merged:
merged[key] += value # Sum values for common keys
else:
merged[key] = value
print(f"Merged with sum for common keys: {merged}")
# 10. Invert dictionary (handle non-unique values)
def invert_dict(d):
inverted = {}
for key, value in d.items():
inverted.setdefault(value, []).append(key)
return inverted
sample = {"a": 1, "b": 2, "c": 1, "d": 3, "e": 2}
inverted = invert_dict(sample)
print(f"Inverted dictionary: {inverted}")
# 11. Find common keys between two dictionaries
dict_a = {"a": 1, "b": 2, "c": 3, "d": 4}
dict_b = {"b": 20, "c": 30, "e": 50, "f": 60}
common_keys = set(dict_a.keys()) & set(dict_b.keys())
print(f"Common keys: {common_keys}")
# 12. Dictionary difference
keys_only_in_a = set(dict_a.keys()) - set(dict_b.keys())
keys_only_in_b = set(dict_b.keys()) - set(dict_a.keys())
print(f"Keys only in dict_a: {keys_only_in_a}")
print(f"Keys only in dict_b: {keys_only_in_b}")
print("\n=== Exercise 6: Real-world Problems ===")
# 13. Group items by category
items = [
{"name": "apple", "category": "fruit", "price": 1.0},
{"name": "banana", "category": "fruit", "price": 0.5},
{"name": "carrot", "category": "vegetable", "price": 0.8},
{"name": "broccoli", "category": "vegetable", "price": 1.2},
{"name": "orange", "category": "fruit", "price": 1.5}
]
# Group by category
category_groups = {}
for item in items:
category = item["category"]
category_groups.setdefault(category, []).append(item["name"])
print(f"Items grouped by category: {category_groups}")
# Calculate total price per category
category_totals = {}
for item in items:
category = item["category"]
category_totals[category] = category_totals.get(category, 0) + item["price"]
print(f"Total price per category: {category_totals}")
# 14. Find the cheapest item in each category
cheapest_per_category = {}
for item in items:
category = item["category"]
if category not in cheapest_per_category or item["price"] < cheapest_per_category[category]["price"]:
cheapest_per_category[category] = item
print("Cheapest item in each category:")
for category, item in cheapest_per_category.items():
print(f"{category}: {item['name']} (${item['price']})")
# 15. Create a dictionary from two lists with validation
def create_dict_from_lists(keys, values):
"""Create dictionary from two lists. If lengths differ, use None for missing values."""
result = {}
for i, key in enumerate(keys):
result[key] = values[i] if i < len(values) else None
return result
keys = ["name", "age", "city", "email"]
values = ["Alice", 30, "NYC"]
result_dict = create_dict_from_lists(keys, values)
print(f"\nDictionary from lists: {result_dict}")
Key Takeaways
- Python dictionaries are unordered collections of key-value pairs (ordered in Python 3.7+)
- Keys must be hashable (immutable: strings, numbers, tuples), values can be any Python object
- Dictionaries provide O(1) average time complexity for lookups, inserts, and deletes
- Use
{}ordict()to create dictionaries - Key methods:
get(),setdefault(),keys(),values(),items(),pop(),popitem(),update(),copy(),clear() dict[key]raises KeyError for missing keys;dict.get(key, default)returns default- Dictionary comprehension:
{k: v for item in iterable}creates dictionaries concisely - Use
inoperator to check key existence:'key' in dictionary dict.keys(),dict.values(),dict.items()return dynamic view objects- Dictionaries can be nested to represent complex hierarchical data
- Merge dictionaries with
update(),{**d1, **d2}(Python 3.5+), or|operator (Python 3.9+) - Use
collections.defaultdictfor dictionaries with default values dict.copy()creates shallow copy; usecopy.deepcopy()for nested dictionaries