Skip to content

8 min read

American Corners

Dictionaries: key and value

Looking things up by name, not by number

A list finds items by position: students[2] is the third one. That is fine when position carries meaning, but often it does not. If you want to know the price of a coffee or the phone number of a shop, counting to a numeric index is awkward. You want to look it up by a name.

A dictionary does exactly that. It stores pairs, each made of a key you look things up by and a value you get back. You write it with curly braces, and a colon between each key and its value:

prices = {"coffee": 120, "tea": 90, "water": 50}

To read a value, you index with its key instead of a number:

print(prices["coffee"])   # 120

The keys here are strings, but a key can be a number or a tuple too. What a key really has to be is unchangeable all the way down: a tuple of numbers or strings works, while a tuple with a list inside it does not, because the list inside could still change. The values can be anything at all: numbers, strings, even lists or other dictionaries.

Adding, changing and removing

A dictionary is mutable, so it grows and changes freely. You add a new pair by assigning to a key that is not there yet, and you change an existing value by assigning to a key that is:

prices["juice"] = 150     # adds a new pair
prices["tea"] = 100       # changes an existing value
del prices["water"]       # removes the pair for "water"

A frequent trap is reading a key that does not exist. prices["milk"] does not return a blank; it raises a KeyError and stops the program. You can guard against that in two clean ways:

print("milk" in prices)          # False, a safe yes/no test
print(prices.get("milk", 0))     # 0, a default when the key is missing

The in keyword asks whether a key is present. The .get() method fetches a value but lets you name a fallback for when the key is absent, so your program keeps running instead of crashing.

Walking through a dictionary

Looping over a dictionary gives you its keys, and from each key you can reach its value. That lets you visit every pair in turn:

for item in prices:
    print(item, "costs", prices[item])

If you only care about the values, prices.values() hands them to you directly; prices.keys() does the same for the keys. Most of the time, though, looping over the dictionary itself and indexing back in is all you need.

A worked example: counting words

Dictionaries are the natural tool whenever you need to tally things. Suppose you want to count how many times each word appears in a sentence. The key is the word; the value is its running count:

def count_words(sentence):
    counts = {}
    for word in sentence.split():
        if word in counts:
            counts[word] = counts[word] + 1
        else:
            counts[word] = 1
    return counts

print(count_words("mesa mesa taule karrige mesa"))

This prints {'mesa': 3, 'taule': 1, 'karrige': 1}. Walk through the logic: split() breaks the sentence into a list of words, and for each word you either bump a count that already exists or start a fresh one at 1. The same .get() method can shorten the middle:

counts[word] = counts.get(word, 0) + 1

That one line reads "the old count, or 0 if this is the first time, plus one". Tallying with a dictionary is a pattern you will use again and again.

Warning

Reading a missing key with square brackets raises a KeyError and halts your program. When you are not certain a key is there, test with in first or fetch with .get() and a default. This is the single most common dictionary mistake.

Prefer to see it explained? Here is the recorded Code for Albania lecture on this topic.

Try this now

Build a dictionary prices with three items and their prices, like the coffee example. Add a fourth item by assigning to a new key. Then print prices.get("milk", 0) for an item you did not add, and confirm it returns 0 instead of crashing. You have exercised both adding a pair and the safe lookup.

Check yourself

  1. A list finds items by numeric position; a dictionary finds them by key. Give one everyday example where looking up by key is clearly the better fit, and say why.
  2. What is the difference in behaviour between prices["milk"] and prices.get("milk", 0) when the key "milk" is not in the dictionary?
  3. In the word-counting example, what job does the else branch do, and what would go wrong if you deleted it and always ran counts[word] = counts[word] + 1?

Where this lesson comes from

Built from

  • Data Structures and Algorithms
  • Further reading: Brian Heinold, A Practical Introduction to Python Programming

alphaPlan courses are built from taught programmes rather than invented for the web. Where a claim rests on an outside standard or a reported case, it is named above so you can check it rather than take our word for it.

This course was developed by alphaPlan Center from programs delivered in partnership with the American Corners network.

Found something unclear, outdated or improvable? Suggest an improvement