30% off your first 3 months

Get the deal

Lists, dictionaries and sets

by DuckyHelperNov 12, 20264 min read
Computer science

TL;DR:

  • A list keeps items in order and allows duplicates. A dictionary maps keys to values. A set holds unique items with no order.

  • Use a dictionary to count or look things up by key, and a set to remove duplicates or test membership quickly.

  • Counting the words in the cat and the dog and the bird finds 'the' three times, 'and' twice, and each of the other three words once.

You want to know how many times each word appears in a sentence. You could keep a list of words and count by hand, but there is a tool made for the job. Python has three main containers, and counting words is a good test of when to reach for which.

The idea in plain words

  • A list is an ordered collection. You access items by position (starting at 0), the same item can appear more than once, and you can change it.

  • A dictionary (dict) stores pairs of a key and a value. You look up a value by its key, not its position, and each key appears once.

  • A set is an unordered collection of unique items. Adding something that is already there does nothing.

names = ["Ava", "Ben", "Ava"]      # list: order kept, duplicates kept
ages = {"Ava": 15, "Ben": 14}      # dict: look up by key
unique = {"Ava", "Ben", "Ava"}     # set: duplicates collapse

The set unique has just two members, Ava and Ben. Looking up ages['Ava'] gives 15 directly, without searching through the pairs one by one.

Why lookups differ

To find an item in a list, Python checks the items one at a time until it finds a match, so a longer list takes longer. A dictionary or set uses the item's hash, a number computed from it, to jump close to where it is stored. Checking whether something is in a set stays fast even when the set is large. That is the main reason to use them.

Worked example: counting words in a sentence

sentence = "the cat and the dog and the bird"
words = sentence.split()
print(words)

counts = {}
for w in words:
    counts[w] = counts.get(w, 0) + 1
print(counts)

print(len(words))
print(len(set(words)))

Trace it.

  1. split() breaks the sentence at spaces and returns a list: ['the', 'cat', 'and', 'the', 'dog', 'and', 'the', 'bird']. That is 8 words.

  2. counts starts as an empty dictionary.

  3. For each word, counts.get(w, 0) returns the current count, or 0 if the word is new. Adding 1 and storing it back updates the dictionary.

  4. After the loop the counts are 3 for the, 1 for cat, 2 for and, 1 for dog and 1 for bird.

  5. len(set(words)) removes duplicates first, leaving five distinct words.

The program prints the list, then {'the': 3, 'cat': 1, 'and': 2, 'dog': 1, 'bird': 1}, then 8, then 5.

How to check your answer

  • The counts must add up to the number of words: 3 + 1 + 2 + 1 + 1 = 8.

  • The number of keys must equal the number of distinct words: 5.

  • Spot-check one word by counting it by hand. 'the' appears three times.

  • Try a sentence with different capital letters. 'The' and 'the' are different keys unless you lower-case first.

Duplicates: set or dictionary?

Say you want the distinct words but in the order they first appeared. A set would lose the order. A dictionary keeps it, so you can use its keys.

words = ["the", "cat", "and", "the", "dog", "and", "the", "bird"]
distinct = list(dict.fromkeys(words))
print(distinct)

This prints ['the', 'cat', 'and', 'dog', 'bird']. Each word is stored as a key the first time it is seen, later copies are ignored, and the keys stay in insertion order. If the order does not matter, set(words) is simpler.

The most useful operations

A few moves cover most everyday use. For a list:

nums = [10, 20, 30]
print(nums[0])      # 10, the first item
print(nums[-1])     # 30, the last item
nums.append(40)
print(nums[1:3])    # [20, 30], items at positions 1 and 2

The slice nums[1:3] starts at position 1 and stops before position 3, so it returns two items. Sets also support maths-style operations:

a = {1, 2, 3}
b = {2, 3, 4}
print(a & b)    # in both: {2, 3}
print(a | b)    # in either: {1, 2, 3, 4}
print(a - b)    # in a but not b: {1}

These are useful for questions like which students are in both clubs, or which words appear in one text but not another. For plain data you could do it with loops, but the set operators say what you mean in one line.

Combining containers

Real data often nests one container inside another. A list of dictionaries is a natural way to hold a table of records, one dictionary per row.

students = [
    {"name": "Ava", "grade": 9},
    {"name": "Ben", "grade": 10},
]
for s in students:
    print(s["name"], s["grade"])

This prints Ava 9 and then Ben 10. Each pass of the loop gets one dictionary, and the key picks the field you want. A dictionary whose values are lists works the other way round, for example mapping each club name to the list of its members. The shape you choose should match the question you will ask most often.

Choosing between them

Need

Use

Why

Keep things in order, allow repeats

list

Position matters

Find a value by a name

dict

Fast lookup by key

Remove duplicates

set

Each item stored once

Check membership quickly

set or dict

Constant-time on average

Common mistakes

  • Using a list when you keep searching it for items. A set or dictionary is faster.

  • Expecting a set to keep order. It does not guarantee any.

  • Using {} for an empty set. That makes an empty dictionary. Use set().

  • Asking for a missing key with counts['fish'], which raises a KeyError. Use .get() with a default.

  • Changing a list while you loop over it.

Where you will use it next

These three containers carry most real programs: counting, grouping, caching and checking for duplicates. The dictionary's fast lookup is explained in hash tables and why lookups are fast. When code that uses them misbehaves, debugging a program methodically is the place to start.

Frequently asked questions

Can a dictionary key be a list?

No. Keys must be hashable, which means unchangeable types such as strings, numbers and tuples.

Do dictionaries keep order?

In modern Python they keep the order in which keys were inserted. Sets do not guarantee any order.

Get started

DuckyHelper can
do more

It sees your screen and works in any app you use. Try it for 10 minutes, no card.

Get it for Mac, Windows or Linux

Share

Questions and jobs

Do anything

Ask it a question or hand it a job, in any app.

Doing jobs for you is in early access on Mac. Asking works on Mac, Windows and Linux.