Dictionaries & Sets β Python Questions with Answers
Start with the study notes on Dictionaries & Sets (definitions, examples and a quick revision), then work through 30 practice questions, each with the correct answer and a clear explanation of why it is right. When you are ready, take this topic as an interactive quiz to test yourself.
10 easy Β· 15 medium Β· 5 hard Β· Part of Python: Master Python from basics to advanced - 20 topics.
Topic overview
Dictionaries and Sets β lookups by key and unique values
1. Dictionaries
A dictionary (dict) stores key: value pairs. You look values up by key, not by position. Keys are unique.
ages = {"Ana": 21, "Ben": 25}
print(ages["Ana"])
ages["Cy"] = 30 # add a new key
ages["Ana"] = 22 # update an existing key
print(ages)
print(len(ages))
Output21
{'Ana': 22, 'Ben': 25, 'Cy': 30}
3
2. Missing keys: [] vs get()
d[key] raises KeyError if the key is missing.
d.get(key) returns None, or a default you choose, instead.
ages = {"Ana": 21}
print(ages.get("Zoe"))
print(ages.get("Zoe", 0))
print("Ana" in ages, 21 in ages) # in checks KEYS
OutputNone
0
True False
3. Looping over a dictionary
Looping over a dict directly gives its keys.
.values() gives the values, and .items() gives (key, value) pairs.
ages = {"Ana": 21, "Ben": 25}
print(list(ages.keys()), list(ages.values()))
for name, age in ages.items():
print(f"{name} is {age}")
Output['Ana', 'Ben'] [21, 25]
Ana is 21
Ben is 25
Remember: Since Python 3.7, dicts keep keys in the order you added them.
4. Removing and merging
d = {"a": 1, "b": 2, "c": 3}
value = d.pop("a") # remove and return the value
del d["b"]
print(value, d)
x = {"x": 1, "y": 2}
y = {"y": 99, "z": 3}
print(x | y) # merge (Python 3.9+); right side wins
x.update(y)
print(x)
Counting things is one of the most common uses of a dict.
words = ["a", "b", "a", "c", "a"]
counts = {}
for w in words:
counts[w] = counts.get(w, 0) + 1
print(counts)
from collections import Counter
print(Counter(words).most_common(1))
Output{'a': 3, 'b': 1, 'c': 1}
[('a', 3)]
6. Nested dictionaries and keys
Values can themselves be dicts or lists, which is how JSON data looks. Keys must be hashable (immutable): strings, numbers and tuples work, but lists do not.
user = {"name": "Ana", "address": {"city": "Delhi"}}
print(user["address"]["city"])
grid = {(0, 0): "start"} # a tuple key is fine
print(grid[(0, 0)])
OutputDelhi
start
7. Sets
A set is an unordered collection of unique values. Duplicates disappear automatically. Sets have no positions, so s[0] is an error.
Dictionary values are accessed BY KEY, not by position: ages["Ana"] gives 21. There is no ages[0] - dicts aren't indexed by numbers (unless a number IS a key).
Assigning to a NEW key simply creates it: ages["Ben"] = 25. Assigning to an EXISTING key overwrites its value. Dicts have no append().
Adding keysUpdating values
Q6.easy
What does "Ana" in ages check, for a dictionary ages?
ages = {"Ana": 21}
print("Ana" in ages) # True (key)
print(21 in ages) # False!
print(21 in ages.values()) # True
A Whether "Ana" is one of the KEYS
B Whether "Ana" is one of the VALUES
C Whether "Ana" is a key OR a value
D Nothing - in doesn't work on dicts
Answer: A β Whether "Ana" is one of the KEYS
The in operator on a dict tests KEYS only. To search values, use: 21 in ages.values().
in operatorvalues()
Q9.easy
How do you loop over BOTH keys and values at once?
ages = {"Ana": 21, "Ben": 25}
for name, age in ages.items():
print(f"{name} is {age}")
A for k, v in d.items():
B for k, v in d:
C for k, v in d.pairs():
D for k + v in d:
Answer: A β for k, v in d.items():
.items() yields (key, value) tuples which unpack straight into two loop variables - the standard dict-looping pattern.
items()Unpacking
Q13.easy
What does len({"a": 1, "b": 2, "c": 3}) return?
A 6
B 3 - the number of key-value pairs
C 2
D Error
Answer: B β 3 - the number of key-value pairs
len() on a dict counts the PAIRS (keys), not keys+values separately: 3.
len()
Q19.easy
Which line creates a SET of three numbers?
s = {1, 2, 3}
print(type(s)) # <class 'set'>
A s = {1, 2, 3}
B s = [1, 2, 3]
C s = (1, 2, 3)
D s = set[1, 2, 3]
Answer: A β s = {1, 2, 3}
Curly braces WITHOUT colons create a set - an unordered collection of UNIQUE values. (With colons it would be a dict.)
Sets
Q21.easy
What is the output of: print({1, 2, 2, 3, 3, 3})
print({1, 2, 2, 3, 3, 3}) # {1, 2, 3}
A {1, 2, 2, 3, 3, 3}
B {1, 2, 3}
C [1, 2, 3]
D Error
Answer: B β {1, 2, 3}
Sets store each value only ONCE - duplicates are silently discarded: {1, 2, 3}. This is the defining property of a set.
Uniqueness
Q24.easy
Which method adds one element to a set?
s = {1, 2}
s.add(3)
s.add(2) # already there - ignored
print(s) # {1, 2, 3}
A append()
B add()
C insert()
D push()
Answer: B β add()
Sets use .add() (append and insert are list methods). Adding an element that already exists does nothing - no error, no duplicate.
add()Uniqueness
Q29.easy
Which structure best stores each student's marks BY NAME?
A A dict: {"Ana": 92, "Ben": 85}
B A list: [92, 85]
C A set: {92, 85}
D A string: "Ana 92 Ben 85"
Answer: A β A dict: {"Ana": 92, "Ben": 85}
When data is naturally 'look up X by Y', a dict is the right tool - marks by name, prices by product, settings by option. Lists are for ordered sequences, sets for uniqueness.
Choosing data structures
Medium questions (15)
Q3.medium
What happens with:
ages = {"Ana": 21}
print(ages["Zoe"])
Reading a key that doesn't exist raises KeyError. Use .get() when a missing key is possible - it returns None (or your chosen default) instead of crashing.
KeyErrorget()
Q4.medium
What is the difference between ages["Zoe"] and ages.get("Zoe")?
B [] raises KeyError when missing; get() returns None (or a default) instead
C get() is slower and deprecated
D get() also deletes the key
Answer: B β [] raises KeyError when missing; get() returns None (or a default) instead
Square brackets demand the key exists. .get(key, default) is the safe version - perfect when missing keys are normal, like counting or optional settings.
get()Defaults
Q7.medium
What do keys(), values() and items() return for {"a": 1, "b": 2}?
Keys are UNIQUE - assigning to an existing key replaces its value. A dict can never hold the same key twice. (Values, however, may repeat freely.)
Unique keysUpdating
Q11.medium
Which of these CANNOT be a dictionary key?
ok = {(1, 2): "point"} # tuple key - fine
# bad = {[1, 2]: "point"} # TypeError: unhashable type: 'list'
A "name" (a string)
B 42 (an int)
C (1, 2) (a tuple)
D [1, 2] (a list)
Answer: D β [1, 2] (a list)
Keys must be hashable, which in practice means immutable: strings, numbers and tuples are fine; lists, dicts and sets are NOT (they can change, so their hash could change).
HashabilityImmutability
Q12.medium
How do you access "Delhi" in this nested dict?
user = {"name": "Ana", "address": {"city": "Delhi", "pin": 110001}}
Chain the keys: user["address"] returns the inner dict, then ["city"] reads from it. Nested dicts are how JSON-like data is represented in Python.
Nested dictsJSON
Q14.medium
How do you REMOVE the key "Ana" from ages?
ages = {"Ana": 21, "Ben": 25}
age = ages.pop("Ana") # age = 21
del ages["Ben"]
print(ages) # {}
A del ages["Ana"] or ages.pop("Ana")
B ages.remove("Ana")
C ages.delete("Ana")
D ages - "Ana"
Answer: A β del ages["Ana"] or ages.pop("Ana")
del ages["Ana"] deletes the pair; ages.pop("Ana") deletes it AND returns the value. Dicts have no .remove() method (that's for lists and sets).
delpop()
Q16.medium
In Python 3.7+, in what order does a dict keep its keys?
d = {"b": 1, "a": 2}
print(list(d)) # ['b', 'a'] - insertion order
print(sorted(d)) # ['a', 'b'] - sorted view
A Alphabetical order
B Insertion order - the order you added them
C Random order each run
D Sorted by value
Answer: B β Insertion order - the order you added them
Since 3.7, dicts officially preserve insertion order - looping shows keys in the order they were added. They are never auto-sorted; use sorted(d) for that.
Insertion ordersorted()
Q18.medium
What does update() do?
d = {"a": 1}
d.update({"a": 5, "b": 2})
Convert to a set (duplicates vanish), then back to a list. Note: original order may be lost - use list(dict.fromkeys(nums)) to keep order.
set()Deduplication
Q23.medium
What happens with:
s = {10, 20, 30}
print(s[0])
s = {10, 20, 30}
# print(s[0]) # TypeError!
for x in s: # looping is fine
print(x)
A Prints 10
B TypeError - sets are unordered and don't support indexing
C Prints a random element
D Prints {10}
Answer: B β TypeError - sets are unordered and don't support indexing
Sets have no positions - there IS no 'first' element, so s[0] raises TypeError. You can loop over a set or test membership, but never index it.
Unordered collectionsTypeError
Q25.medium
a = {1, 2, 3} and b = {2, 3, 4}. What is a & b?
a = {1, 2, 3}
b = {2, 3, 4}
print(a & b) # {2, 3} - in both
A {1, 2, 3, 4}
B {2, 3}
C {1}
D {4}
Answer: B β {2, 3}
& is INTERSECTION - elements present in BOTH sets: {2, 3}. Think of overlapping circles in a Venn diagram.
IntersectionSet operations
Q26.medium
a = {1, 2, 3} and b = {2, 3, 4}. What is a | b?
print(a | b) # {1, 2, 3, 4} - union
print(a & b) # {2, 3} - intersection
print(a - b) # {1} - difference
A {2, 3}
B {1, 4}
C {1, 2, 3, 4}
D {1}
Answer: C β {1, 2, 3, 4}
| is UNION - every element that appears in EITHER set, duplicates counted once: {1, 2, 3, 4}.
UnionSet operations
Q28.medium
Why is 'x in my_set' much faster than 'x in my_list' for large data?
big = set(range(1_000_000))
print(999_999 in big) # instant, even for huge sets
A It isn't - both are the same speed
B Sets use hashing - membership is found instantly instead of checking items one by one
C Sets are stored in the CPU cache
D Lists compress their data
Answer: B β Sets use hashing - membership is found instantly instead of checking items one by one
A list checks every element until it finds a match (linear time). A set jumps straight to where the value would live using its hash (constant time). With a million items, that's the difference between 1 check and 500,000.
HashingPerformance
Hard questions (5)
Q15.hard
Complete the word-counting pattern:
counts = {}
for word in words:
counts[word] = ______
words = ["a", "b", "a"]
counts = {}
for w in words:
counts[w] = counts.get(w, 0) + 1
print(counts) # {'a': 2, 'b': 1}
A counts.get(word, 0) + 1
B counts[word] + 1
C 1
D word + 1
Answer: A β counts.get(word, 0) + 1
get(word, 0) returns the current count or 0 for a new word, then +1. Option B crashes with KeyError on the first occurrence; option C never counts past 1.
collections.Counter(words) does this in one line.
get()Counting patternCounter
Q17.hard
Which merges two dicts d1 and d2 into a new dict (Python 3.9+)?
a = {"x": 1, "y": 2}
b = {"y": 99, "z": 3}
print(a | b) # {'x': 1, 'y': 99, 'z': 3}
print({**a, **b}) # same, works in older Pythons
A d1 | d2
B d1 + d2
C d1 & d2
D merge(d1, d2)
Answer: A β d1 | d2
The | operator merges dicts (3.9+); on duplicate keys, the RIGHT side wins. d1 + d2 is a TypeError. Older code uses {**d1, **d2} or d1.update(d2).
Merging dictsupdate()
Q20.hard
How do you create an EMPTY set?
a = {}
print(type(a)) # <class 'dict'> !
b = set()
print(type(b)) # <class 'set'>
A s = {}
B s = set()
C s = []
D s = empty_set
Answer: B β s = set()
Gotcha: {} creates an empty DICT, not a set! The only way to make an empty set is set(). This trips up almost everyone once.
set()Common gotchas
Q27.hard
a = {1, 2, 3} and b = {2, 3, 4}. What is a - b?
print(a - b) # {1} - in a, not in b
print(b - a) # {4} - in b, not in a
A {1}
B {4}
C {1, 4}
D {-1, -1, -1}
Answer: A β {1}
Set difference a - b keeps what's in a but NOT in b: only 1. Note it's directional: b - a would give {4}.