Dictionaries and Sets

A beginner-friendly teaching edition — concepts, examples, outputs, mistakes and revision
Big idea: Python already gives us sequences such as strings, lists and tuples. This chapter introduces two important non-sequence collections: dictionaries and sets. A dictionary connects a key to a value, while a set stores unique elements. The chapter finishes by using these ideas in a dynamic data-visualization example.

What You Will Learn

  • Use dictionaries for key–value pairs.
  • Use sets for collections of unique values.
  • Create, initialize and access dictionaries and sets.
  • Iterate through dictionary keys, values and key–value pairs.
  • Add, remove and update dictionary entries.
  • Compare dictionaries and sets.
  • Combine sets with mathematical set operations.
  • Use in and not in.
  • Modify mutable sets with set operators and methods.
  • Create dictionaries and sets with comprehensions.
  • Understand the basic idea of dynamic visualizations.

Chapter Structure

6.1 Introduction6.2 Dictionaries6.3 Sets6.4 Dynamic Visualizations6.5 Wrap-Up

6.1 Introduction

Think about a normal dictionary. You look up a word and get its definition. Python dictionaries use the same basic idea: a key is associated with a value.

A dictionary is an unordered collection of key–value pairs. Its keys must be immutable and unique. A set is an unordered collection of unique immutable elements.

Dictionary
Key → Value

Example: "India" → "in"
Set
Unique values only

Example: {10, 20, 30}
Remember: A dictionary answers "What value belongs to this key?" A set answers "Which unique values are present?"

6.2 Dictionaries

A dictionary stores relationships between keys and values. Keys must be immutable—such as strings, numbers or tuples—and no two entries can have the same key.

Example keysPossible values
Country namesInternet country codes
Decimal numbersRoman numerals
StatesLists of agricultural products
Hospital patientsTuples of vital signs
Baseball playersBatting averages
Inventory codesQuantity in stock

6.2.1 Creating a Dictionary

Use curly braces {}. Each entry has the form key: value.

country_codes = {
    'Finland': 'fi',
    'South Africa': 'za',
    'Nepal': 'np'
}

print(country_codes)
{'Finland': 'fi', 'South Africa': 'za', 'Nepal': 'np'}

An empty dictionary is simply:

data = {}
Important: Do not write program logic that depends on the displayed order of dictionary entries. Conceptually, treat the dictionary as a key–value collection rather than as a sequence.

Dictionary Length and Empty Dictionaries

country_codes = {'Finland': 'fi', 'South Africa': 'za', 'Nepal': 'np'}

print(len(country_codes))

if country_codes:
    print('country_codes is not empty')
else:
    print('country_codes is empty')
3
country_codes is not empty

An empty dictionary evaluates to False; a non-empty dictionary evaluates to True.

6.2.2 Iterating through a Dictionary

A dictionary can be processed with a for loop. The items() method gives key–value pairs, which can be unpacked into two variables.

days_per_month = {
    'January': 31,
    'February': 28,
    'March': 31
}

for month, days in days_per_month.items():
    print(f'{month} has {days} days')
January has 31 days
February has 28 days
March has 31 days
Easy way to remember: items() → both key and value.

6.2.3 Basic Dictionary Operations

Accessing a Value

roman_numerals = {
    'I': 1,
    'II': 2,
    'III': 3,
    'V': 5,
    'X': 100
}

print(roman_numerals['V'])
5

Updating an Existing Value

roman_numerals['X'] = 10
print(roman_numerals)
{'I': 1, 'II': 2, 'III': 3, 'V': 5, 'X': 10}

Adding a New Key–Value Pair

roman_numerals['L'] = 50
print(roman_numerals)
{'I': 1, 'II': 2, 'III': 3, 'V': 5, 'X': 10, 'L': 50}

If the key does not already exist, assignment adds a new pair. String keys are case-sensitive, so accidentally using a different case can create a new key.

Removing a Key–Value Pair

del roman_numerals['III']

You can also use pop(), which removes a key and returns its value:

value = roman_numerals.pop('V')
print(value)
5

Membership Testing

For dictionaries, in and not in test for keys.

codes = {'India': 'in', 'Japan': 'jp'}

print('India' in codes)
print('USA' in codes)
True
False
Common mistake: 'in' on a dictionary checks keys, not values.

6.2.4 Dictionary Methods keys and values

keys() provides the dictionary's keys, while values() provides its values.

grades = {'Ann': 90, 'Bob': 85, 'Cara': 90}

print(grades.keys())
print(grades.values())

You can iterate through them:

for name in grades.keys():
    print(name)

for grade in grades.values():
    print(grade)
Memory trick: keys() → names/labels; values() → stored data.

6.2.5 Dictionary Comparisons

Dictionaries can be compared for equality and inequality. Two dictionaries are equal when they contain the same key–value pairs.

a = {'x': 1, 'y': 2}
b = {'y': 2, 'x': 1}

print(a == b)
print(a != b)
True
False

6.2.6 Example: Dictionary of Student Grades

A dictionary is a natural way to associate a student with a grade.

grades = {
    'Susan': 92,
    'Mike': 85,
    'John': 78
}

print(grades['Susan'])

grades['John'] = 88
grades['Emma'] = 95

for name, grade in grades.items():
    print(f'{name}: {grade}')

The important idea is the mapping:

Student nameGrade

6.2.7 Example: Word Counts

Dictionaries are especially useful when counting how often something occurs. The word can be the key and its count can be the value.

text = 'red blue red green blue red'
counts = {}

for word in text.split():
    if word in counts:
        counts[word] += 1
    else:
        counts[word] = 1

print(counts)
{'red': 3, 'blue': 2, 'green': 1}
Pattern to remember:
If the key exists → increase its value.
If the key does not exist → create it with the starting value.

6.2.8 Dictionary Method update

update() adds key–value pairs from another mapping/iterable of pairs and can replace values for keys that already exist.

student = {'name': 'Aman', 'grade': 80}

student.update({'grade': 90, 'city': 'Delhi'})

print(student)
{'name': 'Aman', 'grade': 90, 'city': 'Delhi'}

6.2.9 Dictionary Comprehensions

A dictionary comprehension is a compact way to build a dictionary from an iterable.

squares = {number: number ** 2 for number in range(1, 6)}
print(squares)
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Read it as:

take a numbercalculate its squarestore number → square
Do not rush into comprehensions. First understand the normal for loop, then learn the shorter comprehension form.

6.3 Sets

A set is an unordered collection of unique elements. Duplicate values are automatically removed.

numbers = [0, 1, 2, 3, 4, 5, 0, 1, 2]

unique_numbers = set(numbers)

print(unique_numbers)
{0, 1, 2, 3, 4, 5}

To create an empty set, use:

empty_set = set()
Important: {} creates an empty dictionary, not an empty set.

Sets Are Iterable

colors = {'red', 'green', 'blue'}

for color in colors:
    print(color)

Because a set is unordered, do not depend on a particular iteration order.

Membership in a Set

colors = {'red', 'green', 'blue'}

print('red' in colors)
print('purple' not in colors)
True
True

Frozenset: An Immutable Set Type

Normal sets are mutable, so their contents can be changed. A frozenset is an immutable set. This makes it possible for a set to contain frozensets as elements.

fixed = frozenset([1, 2, 3])
print(fixed)

6.3.1 Comparing Sets

Set comparison is based on membership, not on order.

{1, 3, 5} == {3, 5, 1}
True

Subset

< checks for a proper subset. <= checks for a subset that may also be equal.

{1, 3} < {1, 3, 5}
{1, 3} <= {1, 3, 5}
{1, 3, 5}.issubset({1, 3, 5})

Superset

> checks for a proper superset. >= checks for a superset that may also be equal.

{1, 3, 5} > {1, 3}
{1, 3, 5}.issuperset({1, 3})
OperationMeaning
A == BSame elements
A != BDifferent elements
A < BA is a proper subset of B
A <= BA is a subset of B
A > BA is a proper superset of B
A >= BA is a superset of B

6.3.2 Mathematical Set Operations

Python provides the familiar mathematical operations: union, intersection, difference and symmetric difference.

Union — |

All unique elements from both sets.

{1, 3, 5} | {2, 3, 4}
{1, 2, 3, 4, 5}

Intersection — &

Only elements common to both sets.

{1, 3, 5} & {2, 3, 4}
{3}

Difference — -

Elements in the left set that are not in the right set.

{1, 3, 5} - {2, 3, 4}
{1, 5}

Symmetric Difference — ^

Elements that are in either set, but not in both.

{1, 3, 5} ^ {2, 3, 4}
{1, 2, 4, 5}

Disjoint Sets

Two sets are disjoint when they have no common elements.

{1, 2}.isdisjoint({3, 4})
True
SymbolNameEasy meaning
|UnionEverything from both
&IntersectionCommon elements
-DifferenceLeft only
^Symmetric differenceIn one, but not both

6.3.3 Mutable Set Operators and Methods

The mathematical operators above create a new set. Mutable operations modify an existing set.

colors = {'red', 'green'}
colors |= {'blue', 'yellow'}

print(colors)

The update() method also performs a union while modifying the set:

colors = {'red', 'green'}
colors.update(['blue', 'yellow'])

print(colors)

Other mutable set operations include:

  • &= — update with intersection
  • -= — update with difference
  • ^= — update with symmetric difference

Useful set methods also include add(), remove(), discard(), clear() and pop().

colors = {'red', 'green'}

colors.add('blue')
colors.remove('green')
print(colors)
Be careful with remove(): it expects the element to exist. When you specifically want a non-erroring removal for a missing element, discard() is useful.

6.3.4 Set Comprehensions

Set comprehensions provide a concise way to create sets.

squares = {number ** 2 for number in range(1, 6)}
print(squares)
{1, 4, 9, 16, 25}

Because the result is a set, duplicate results are kept only once.

6.4 Intro to Data Science: Dynamic Visualizations

The previous chapter introduced static visualization of die-roll results. This chapter takes the same general idea and makes the visualization dynamic.

Static visualization: the final graph is drawn after the calculations.
Dynamic visualization: the graph keeps updating so you can watch the data change.

The chapter uses Seaborn and Matplotlib, together with Matplotlib's animation capabilities, to make the die-roll bar chart "come alive."

6.4.1 How Dynamic Visualization Works

A dynamic visualization is built from a sequence of animation frames. Each frame specifies what should change during one update.

Roll diceUpdate frequenciesClear/update plotDraw bars + textNext frame

Matplotlib's FuncAnimation drives these frame-by-frame updates. You define an update function and pass it to the animation system.

In the example, every frame:

  • rolls the die a specified number of times,
  • updates the die frequencies,
  • clears the current plot,
  • creates updated bars,
  • creates updated frequency and percentage text.

The example uses roughly 30 frames per second when the interval is 33 milliseconds, although actual performance depends on the computer and work done in each frame.

6.4.2 Implementing a Dynamic Visualization

The dynamic die-roll script uses the same basic Seaborn and Matplotlib ideas from the previous chapter, but reorganizes them around animation.

Two Important Command-Line Arguments

ArgumentMeaning
number_of_framesHow many animation frames will be displayed.
rolls_per_frameHow many die rolls happen during each frame.

For example:

ipython RollDieDynamic.py 6000 1

This means 6000 frames and one roll per frame, for 6000 total rolls.

For a much faster simulation:

ipython RollDieDynamic.py 10000 600

This performs 600 rolls per frame. Across 10,000 frames, that is 6,000,000 total rolls.

Why increase rolls per frame? Displaying animation frames is relatively slow compared with the CPU's ability to perform die rolls. Rolling more dice per frame lets the program process many more rolls while keeping the animation practical.

The update Function

FuncAnimation calls the update function once for each frame. The function receives the frame information and the values needed to update the visualization.

def update(frame_number, rolls, faces):
    # roll dice
    # update frequencies
    # clear/update the plot
    # draw bars
    # display frequency and percentage text
    pass

The key idea is not memorizing every line of plotting code. Understand the loop:

Frame 1update graphFrame 2update graphFrame 3update graph...

Dynamic Visualization and the Law of Large Numbers

As more die rolls occur, the percentages tend to move toward the expected probability for each face. For a fair six-sided die, each face is expected to occur about 16.667% of the time.

With 6,000,000 rolls, the expected count for each face is about 1,000,000. Watching the bars and percentages approach these values makes the law of large numbers visually understandable.

Important data-science lesson: A simulation becomes more stable as the number of observations grows. The dynamic graph lets you watch this convergence happen instead of seeing only the final result.

Quick Concept Map

Dictionary → key → value

Dictionary operations → access → update → add → delete → search

Dictionary iteration → keys → values → items

Dictionary comprehension → compact dictionary creation

Set → unique values

Set comparison → equality → subset → superset

Set mathematics → union → intersection → difference → symmetric difference

Set mutation → add/remove/update

Set comprehension → compact set creation

Dynamic visualization → frames → update function → animated graph

Dictionary vs Set vs List

CollectionMain ideaTypical use
ListOrdered sequence of elementsStore items where position matters
DictionaryKey → value mappingLook up data by a key
SetUnique elementsRemove duplicates / membership / set mathematics

Common Mistakes

  1. Using {} when you want an empty set. Use set().
  2. Trying to use a mutable object as a dictionary key or set element.
  3. Forgetting that dictionary membership with in checks keys.
  4. Depending on a dictionary/set display order.
  5. Expecting a set to keep duplicate values.
  6. Confusing union with intersection.
  7. Forgetting that remove() expects the element to be present.
  8. Trying to access a dictionary key that does not exist.
  9. Trying to memorize comprehension syntax before understanding the normal loop.
  10. Thinking a dynamic visualization is just a static plot—it repeatedly updates the display frame by frame.

Remember These Points

  • Dictionary: key → value.
  • Dictionary keys must be immutable and unique.
  • items() gives key–value pairs.
  • keys() gives keys; values() gives values.
  • in on a dictionary tests keys.
  • Set: unique elements.
  • set() creates an empty set.
  • Set order should not be relied upon.
  • | union, & intersection, - difference, ^ symmetric difference.
  • FuncAnimation repeatedly calls an update function to create animation.

Revision Questions

  1. What is a dictionary?
  2. What rules apply to dictionary keys?
  3. How do you create an empty dictionary?
  4. How do you access, update, add and delete a dictionary entry?
  5. What is the difference between keys(), values() and items()?
  6. What does in test when used with a dictionary?
  7. Why are dictionaries useful for word counting?
  8. What is a dictionary comprehension?
  9. What is a set?
  10. How do you create an empty set?
  11. Why are duplicate values removed from a set?
  12. What is a subset? What is a superset?
  13. Explain union, intersection, difference and symmetric difference.
  14. What is the difference between a normal set and a frozenset?
  15. What is a dynamic visualization?
  16. What does FuncAnimation do?
  17. What are number_of_frames and rolls_per_frame?

Practice Programs

1. Student dictionary
Create a dictionary containing five students and their grades. Print all students and grades, then update one grade.
2. Word counter
Ask the user for a sentence and build a dictionary containing the count of every word.
3. Unique numbers
Read a list containing duplicate numbers and use a set to produce only the unique values.
4. Set mathematics
Create two sets of numbers and demonstrate union, intersection, difference and symmetric difference.
5. Dictionary comprehension
Create a dictionary mapping numbers 1–10 to their cubes.
6. Set comprehension
Create a set containing the squares of numbers 1–10.

Chapter Wrap-Up

This chapter introduced two powerful built-in collections. Dictionaries organize data as key–value pairs, making them ideal for lookup and counting tasks. Sets store unique values and support useful mathematical operations such as union, intersection, difference and symmetric difference.

You also learned how comprehensions provide compact ways to create dictionaries and sets. Finally, the data-science section extended the earlier die-roll simulation into a dynamic visualization, where Matplotlib repeatedly updates the graph through animation frames. The visualization makes the convergence of die-roll frequencies toward their expected percentages easier to see.

Next step: Once dictionaries and sets are comfortable, the next chapter moves into array-oriented programming with NumPy, which is especially important when working with larger amounts of numerical data.

Teaching note: This page is a simplified teaching edition based on the chapter organization and concepts in the supplied Python for Programmers source. Examples are rewritten for learning clarity rather than reproduced verbatim.