πŸŽ“ Velnov

🐍 Python · Topic 8 of 20

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()

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

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)
Output1 {'c': 3}
{'x': 1, 'y': 99, 'z': 3}
{'x': 1, 'y': 99, 'z': 3}

5. The counting pattern

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.

s = {1, 2, 2, 3, 3, 3}
print(s)
s.add(4)
s.add(2)          # already there: ignored
print(s, len(s))
print(type({}), type(set()))
Output{1, 2, 3}
{1, 2, 3, 4} 4
<class 'dict'> <class 'set'>

Remember: {} is an empty dict. An empty set must be written set().

8. Set operations

a = {1, 2, 3}
b = {2, 3, 4}
print(a | b, a & b)
print(a - b, a ^ b)
Output{1, 2, 3, 4} {2, 3}
{1} {1, 4}

9. Why sets are useful

nums = [3, 1, 3, 2, 1]
print(list(dict.fromkeys(nums)))
big = set(range(1_000_000))
print(999_999 in big)
Output[3, 1, 2]
True

10. Common misconceptions

MisconceptionCorrect understanding
{} creates an empty set.{} is an empty dict; use set().
21 in ages checks the values.in checks keys; use 21 in ages.values().
d[key] returns None when the key is missing.It raises KeyError; get() returns None.
Sets keep items in insertion order and allow s[0].Sets are unordered and cannot be indexed.
A list can be a dictionary key.Keys must be hashable; use a tuple instead.

11. Quick revision

dict
Key: value pairs, looked up by key.
get()
Safe lookup with an optional default.
items()
(key, value) pairs for looping.
KeyError
Raised when a key is missing.
set
Unordered collection of unique values.
Union |
Everything in either set.
Intersection &
What is in both sets.
Hashable
Can be a key or set item (immutable).

12. Test your understanding

  1. How do you read Ana's age from ages?

    Show answer

    ages["Ana"]

  2. What does ages.get("Zoe", 0) return if Zoe is missing?

    Show answer

    0

  3. What does looping directly over a dict give you?

    Show answer

    Its keys.

  4. How do you loop over keys and values together?

    Show answer

    for k, v in d.items():

  5. How do you create an empty set?

    Show answer

    set()

  6. What is {1, 2, 3} & {2, 3, 4}?

    Show answer

    {2, 3}

  7. How do you remove duplicates from a list?

    Show answer

    list(set(nums)), or list(dict.fromkeys(nums)) to keep order.

  8. Why is x in a set faster than x in a list?

    Show answer

    Sets use hashing to jump straight to the value.

Key takeaway: Use a dict when you look things up by a key, and a set when you need unique values or fast membership tests.

Notes written by Velnov. Every code example with an output was run in Python 3 to check that the output shown is exactly what Python prints.

Key concepts in this topic

DictionariesKey-value pairsKey accessKeyErrorget()DefaultsAdding keysUpdating valuesin operatorvalues()Dict viewsitems()Iterating dictsUnpackingUnique keysUpdatingHashabilityImmutabilityNested dictsJSONlen()delpop()Counting pattern

Jump to: Easy Β· Medium Β· Hard

Easy questions (10)

Q1. easy

Which line creates a dictionary mapping names to ages?

ages = {"Ana": 21, "Ben": 25}
print(ages["Ana"])   # 21
  1. A ages = {"Ana": 21, "Ben": 25}
  2. B ages = ["Ana", 21, "Ben", 25]
  3. C ages = ("Ana": 21, "Ben": 25)
  4. D ages = dict["Ana"=21]

Answer: A β€” ages = {"Ana": 21, "Ben": 25}

Dictionaries use curly braces with key: value pairs. Each key maps to a value - like a real dictionary maps words to meanings.

DictionariesKey-value pairs

Q2. easy

How do you read Ana's age from ages = {"Ana": 21, "Ben": 25}?

ages = {"Ana": 21, "Ben": 25}
print(ages["Ana"])   # 21
# print(ages[0])      # KeyError!
  1. A ages[0]
  2. B ages["Ana"]
  3. C ages.Ana
  4. D ages("Ana")

Answer: B β€” ages["Ana"]

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).

Key accessKeyError

Q5. easy

How do you ADD a new pair to ages = {"Ana": 21}?

ages = {"Ana": 21}
ages["Ben"] = 25     # add
ages["Ana"] = 22     # update existing
print(ages)           # {'Ana': 22, 'Ben': 25}
  1. A ages["Ben"] = 25
  2. B ages.append("Ben", 25)
  3. C ages.add("Ben": 25)
  4. D ages + {"Ben": 25}

Answer: A β€” ages["Ben"] = 25

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
  1. A Whether "Ana" is one of the KEYS
  2. B Whether "Ana" is one of the VALUES
  3. C Whether "Ana" is a key OR a value
  4. 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}")
  1. A for k, v in d.items():
  2. B for k, v in d:
  3. C for k, v in d.pairs():
  4. 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?

  1. A 6
  2. B 3 - the number of key-value pairs
  3. C 2
  4. 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'>
  1. A s = {1, 2, 3}
  2. B s = [1, 2, 3]
  3. C s = (1, 2, 3)
  4. 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}
  1. A {1, 2, 2, 3, 3, 3}
  2. B {1, 2, 3}
  3. C [1, 2, 3]
  4. 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}
  1. A append()
  2. B add()
  3. C insert()
  4. 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?

  1. A A dict: {"Ana": 92, "Ben": 85}
  2. B A list: [92, 85]
  3. C A set: {92, 85}
  4. 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"])

ages = {"Ana": 21}
print(ages.get("Zoe"))        # None
print(ages.get("Zoe", 0))     # 0 (custom default)
  1. A Prints None
  2. B Prints 0
  3. C KeyError: 'Zoe'
  4. D Adds Zoe automatically

Answer: C β€” KeyError: '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")?

config = {"theme": "dark"}
size = config.get("font_size", 14)   # 14 - safe default
  1. A No difference
  2. B [] raises KeyError when missing; get() returns None (or a default) instead
  3. C get() is slower and deprecated
  4. 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}?

d = {"a": 1, "b": 2}
print(list(d.keys()))    # ['a', 'b']
print(list(d.values()))  # [1, 2]
print(list(d.items()))   # [('a', 1), ('b', 2)]
  1. A keys: a,b - values: 1,2 - items: pairs ('a',1),('b',2)
  2. B All three return the same thing
  3. C keys: 1,2 - values: a,b - items: nothing
  4. D They return strings

Answer: A β€” keys: a,b - values: 1,2 - items: pairs ('a',1),('b',2)

Three views of a dict: .keys() gives the keys, .values() the values, .items() gives (key, value) tuples - the one you loop over when you need both.

Dict viewsitems()

Q8. medium

What does this print? for k in {"a": 1, "b": 2}: print(k)

d = {"a": 1, "b": 2}
for k in d:               # keys: a b
for v in d.values():      # values: 1 2
for k, v in d.items():    # both: a 1 / b 2
  1. A a b (the keys)
  2. B 1 2 (the values)
  3. C a 1 b 2
  4. D Error

Answer: A β€” a b (the keys)

Looping over a dict directly gives its KEYS. For values loop over .values(); for both, loop over .items().

Iterating dictsitems()

Q10. medium

What is the output? d = {"x": 1} d["x"] = 99 print(d)

d = {"x": 1}
d["x"] = 99      # overwrite
print(d)          # {'x': 99}
  1. A {'x': 1, 'x': 99}
  2. B {'x': 99}
  3. C KeyError
  4. D {'x': [1, 99]}

Answer: B β€” {'x': 99}

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'
  1. A "name" (a string)
  2. B 42 (an int)
  3. C (1, 2) (a tuple)
  4. 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}}

user = {"name": "Ana",
        "address": {"city": "Delhi", "pin": 110001}}
print(user["address"]["city"])   # Delhi
  1. A user["address"]["city"]
  2. B user["city"]
  3. C user.address.city
  4. D user["address.city"]

Answer: A β€” user["address"]["city"]

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)              # {}
  1. A del ages["Ana"] or ages.pop("Ana")
  2. B ages.remove("Ana")
  3. C ages.delete("Ana")
  4. 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
  1. A Alphabetical order
  2. B Insertion order - the order you added them
  3. C Random order each run
  4. 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})

d = {"a": 1}
d.update({"a": 5, "b": 2})
print(d)   # {'a': 5, 'b': 2}
  1. A d becomes {'a': 5, 'b': 2} - existing keys overwritten, new ones added
  2. B d becomes {'a': 1, 'b': 2} - existing keys kept
  3. C Error - duplicate key
  4. D d is replaced entirely by the new dict

Answer: A β€” d becomes {'a': 5, 'b': 2} - existing keys overwritten, new ones added

.update() copies pairs from another dict into this one: existing keys get the new values, unknown keys are added. The dict is modified in place.

update()Merging

Q22. medium

What is the classic one-liner to remove duplicates from a list?

nums = [3, 1, 3, 2, 1]
print(list(set(nums)))           # e.g. [1, 2, 3]
print(list(dict.fromkeys(nums))) # [3, 1, 2] - keeps order
  1. A unique = list(set(nums))
  2. B unique = nums.unique()
  3. C unique = dedupe(nums)
  4. D unique = nums - duplicates

Answer: A β€” unique = list(set(nums))

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)
  1. A Prints 10
  2. B TypeError - sets are unordered and don't support indexing
  3. C Prints a random element
  4. 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
  1. A {1, 2, 3, 4}
  2. B {2, 3}
  3. C {1}
  4. 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
  1. A {2, 3}
  2. B {1, 4}
  3. C {1, 2, 3, 4}
  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
  1. A It isn't - both are the same speed
  2. B Sets use hashing - membership is found instantly instead of checking items one by one
  3. C Sets are stored in the CPU cache
  4. 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}
  1. A counts.get(word, 0) + 1
  2. B counts[word] + 1
  3. C 1
  4. 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
  1. A d1 | d2
  2. B d1 + d2
  3. C d1 & d2
  4. 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'>
  1. A s = {}
  2. B s = set()
  3. C s = []
  4. 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
  1. A {1}
  2. B {4}
  3. C {1, 4}
  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}.

DifferenceSet operations

Q30. hard

What does dict.fromkeys(["a", "b"], 0) create?

scores = dict.fromkeys(["Ana", "Ben"], 0)
print(scores)   # {'Ana': 0, 'Ben': 0}
  1. A {'a': 0, 'b': 0}
  2. B {0: 'a', 0: 'b'}
  3. C ['a', 'b', 0]
  4. D Error

Answer: A β€” {'a': 0, 'b': 0}

fromkeys() builds a dict with the given keys, all mapped to the same default value: {'a': 0, 'b': 0}. Handy for initializing counters or settings.

  • Careful with a mutable default like [] - all keys would share ONE list.

fromkeys()Initialization

Practice β€œDictionaries & Sets” as a quiz