Python · Syntax · Beginner
Dictionary Methods
Learn all essential dictionary methods and dict comprehensions for clean and efficient data manipulation.
Quick topic start and explanations before exercises (exercises below):
Dict Comprehension & Nested Dicts
#Dictionary Methods Reference
#Exercises:
Safe Config Read
#Write a function `get_setting(config, key, default=None)` that safely reads a value from a config dictionary. If the key exists, return its value; otherwise return `default`. Example: `get_setting({"debug": True}, "debug")` → `True`, `get_setting({"debug": True}, "port", 8080)` → `8080`.
def get_setting(config, key, default=None):
pass
print(get_setting({"debug": True}, "debug")) # True
print(get_setting({"debug": True}, "port", 8080)) # 8080
print(get_setting({"debug": True}, "host")) # None
Solution
def get_setting(config, key, default=None):
return config.get(key, default)
print(get_setting({"debug": True}, "debug")) # True
print(get_setting({"debug": True}, "port", 8080)) # 8080
print(get_setting({"debug": True}, "host")) # None
Word Frequency
#Write a function `word_freq(text)` that returns a dictionary mapping each word to how many times it appears. Words should be lowercased and stripped of punctuation (you can assume only spaces separate words for simplicity). Example: `word_freq("the cat sat the cat")` → `{"the": 2, "cat": 2, "sat": 1}`.
def word_freq(text):
pass
print(word_freq("the cat sat the cat"))
# {"the": 2, "cat": 2, "sat": 1}
Solution
def word_freq(text):
counts = {}
for word in text.lower().split():
counts[word] = counts.get(word, 0) + 1
return counts
print(word_freq("the cat sat the cat"))
# {"the": 2, "cat": 2, "sat": 1}
Merge with Override
#Write a function `merge(base, overrides)` that returns a new dictionary with all keys from `base`, but any key present in `overrides` takes the value from `overrides`. The original dicts must not be modified. Example: `merge({"a": 1, "b": 2}, {"b": 99, "c": 3})` → `{"a": 1, "b": 99, "c": 3}`.
def merge(base, overrides):
pass
print(merge({"a": 1, "b": 2}, {"b": 99, "c": 3}))
# {"a": 1, "b": 99, "c": 3}
Solution
def merge(base, overrides):
return {**base, **overrides}
print(merge({"a": 1, "b": 2}, {"b": 99, "c": 3}))
# {"a": 1, "b": 99, "c": 3}
Remove Key Safely
#Write a function `remove_key(d, key)` that removes `key` from dictionary `d` if it exists, and returns the removed value. If the key does not exist, return `None` without raising an error. The function should modify `d` in place. Example: `d = {"a": 1, "b": 2}; remove_key(d, "a")` → returns `1`, `d` becomes `{"b": 2}`.
def remove_key(d, key):
pass
d = {"a": 1, "b": 2}
print(remove_key(d, "a")) # 1
print(d) # {"b": 2}
print(remove_key(d, "x")) # None
Solution
def remove_key(d, key):
return d.pop(key, None)
d = {"a": 1, "b": 2}
print(remove_key(d, "a")) # 1
print(d) # {"b": 2}
print(remove_key(d, "x")) # None
Squares Dict
#Write a function `squares_dict(n)` using a dict comprehension that returns a dictionary where keys are integers from 1 to `n` and values are their squares. Example: `squares_dict(5)` → `{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}`.
def squares_dict(n):
pass
print(squares_dict(5))
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Solution
def squares_dict(n):
return {i: i ** 2 for i in range(1, n + 1)}
print(squares_dict(5))
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Filter by Value
#Write a function `filter_dict(d, min_value)` that returns a new dictionary containing only the key-value pairs where the value is greater than or equal to `min_value`. Example: `filter_dict({"a": 5, "b": 1, "c": 8, "d": 3}, 4)` → `{"a": 5, "c": 8}`.
def filter_dict(d, min_value):
pass
print(filter_dict({"a": 5, "b": 1, "c": 8, "d": 3}, 4))
# {"a": 5, "c": 8}
Solution
def filter_dict(d, min_value):
return {k: v for k, v in d.items() if v >= min_value}
print(filter_dict({"a": 5, "b": 1, "c": 8, "d": 3}, 4))
# {"a": 5, "c": 8}
Invert Dictionary
#Write a function `invert(d)` that swaps keys and values in a dictionary and returns the new inverted dict. Assume all values are unique and hashable. Example: `invert({"a": 1, "b": 2, "c": 3})` → `{1: "a", 2: "b", 3: "c"}`.
def invert(d):
pass
print(invert({"a": 1, "b": 2, "c": 3}))
# {1: "a", 2: "b", 3: "c"}
Solution
def invert(d):
return {v: k for k, v in d.items()}
print(invert({"a": 1, "b": 2, "c": 3}))
# {1: "a", 2: "b", 3: "c"}
Group by First Letter
#Write a function `group_by_letter(words)` that returns a dictionary where each key is a letter and the value is a sorted list of words starting with that letter. Example: `group_by_letter(["apple", "ant", "banana", "bear"])` → `{"a": ["ant", "apple"], "b": ["banana", "bear"]}`.
def group_by_letter(words):
pass
print(group_by_letter(["apple", "ant", "banana", "bear"]))
# {"a": ["ant", "apple"], "b": ["banana", "bear"]}
Solution
def group_by_letter(words):
result = {}
for word in words:
key = word[0]
result.setdefault(key, []).append(word)
for key in result:
result[key].sort()
return result
print(group_by_letter(["apple", "ant", "banana", "bear"]))
# {"a": ["ant", "apple"], "b": ["banana", "bear"]}
Nested Safe Access
#Write a function `deep_get(data, *keys)` that safely accesses nested dictionary values using a chain of keys. Return `None` if any key is missing. Example: `deep_get({"user": {"address": {"city": "Kyiv"}}}, "user", "address", "city")` → `"Kyiv"`, `deep_get({"user": {}}, "user", "address", "city")` → `None`.
def deep_get(data, *keys):
pass
user = {"user": {"address": {"city": "Kyiv"}}}
print(deep_get(user, "user", "address", "city")) # Kyiv
print(deep_get(user, "user", "phone")) # None
Solution
def deep_get(data, *keys):
for key in keys:
if not isinstance(data, dict):
return None
data = data.get(key)
return data
user = {"user": {"address": {"city": "Kyiv"}}}
print(deep_get(user, "user", "address", "city")) # Kyiv
print(deep_get(user, "user", "phone")) # None
Dict from Two Lists
#Write a function `zip_to_dict(keys, values)` that creates a dictionary from two lists of equal length. If the lists have different lengths, raise a `ValueError` with message `"Lists must have the same length"`. Example: `zip_to_dict(["a", "b", "c"], [1, 2, 3])` → `{"a": 1, "b": 2, "c": 3}`.
def zip_to_dict(keys, values):
pass
print(zip_to_dict(["a", "b", "c"], [1, 2, 3]))
# {"a": 1, "b": 2, "c": 3}
zip_to_dict(["x", "y"], [1, 2, 3]) # raises ValueError
Solution
def zip_to_dict(keys, values):
if len(keys) != len(values):
raise ValueError("Lists must have the same length")
return dict(zip(keys, values))
print(zip_to_dict(["a", "b", "c"], [1, 2, 3]))
# {"a": 1, "b": 2, "c": 3}
try:
zip_to_dict(["x", "y"], [1, 2, 3])
except ValueError as e:
print(e)