Programming and IT

Python: dictionaries

A dictionary stores key–value pairs and finds a value by its key in constant time, however large it grows. It is the workhorse for counting, grouping and settings. Below: creating dictionaries, safe access, iteration and the places where a dictionary does not behave the way people expect.

Updated
In this article

Creating a dictionary and what a key must be#

prices = {"tea": 120, "coffee": 250}
empty = {}                      # a dictionary, not a set
from_pairs = dict([("a", 1), ("b", 2)])
print(prices["tea"], len(prices))   # 120 2

A key can only be an immutable (hashable) value: a string, a number, a tuple, a boolean. A list cannot be a key — trying gives TypeError: unhashable type: 'list'. A value can be anything, including another dictionary.

Insertion order is preserved: since Python 3.7 this is not an implementation accident but a language guarantee. Iterating over a dictionary yields the keys in the order they were added.

Access without KeyError#

Square brackets raise KeyError when the key is missing. When a missing key is a normal situation, use get:

print(prices.get("cocoa"))        # None
print(prices.get("cocoa", 0))     # 0
print("cocoa" in prices)          # False
prices["cocoa"] = 90              # adding also uses brackets

The in operator checks keys, not values; for values you need in prices.values().

The related setdefault method returns the value for a key, and if the key is missing it stores the given default and returns that. It is handy for grouping:

groups = {}
for word in ["apple", "avocado", "banana", "blueberry", "cherry"]:
    groups.setdefault(word[0], []).append(word)
print(groups)
  # {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}

Iteration and the three views#

for key in prices:
    print(key, prices[key])

for key, value in prices.items():
    print(key, "→", value)

print(list(prices.keys()))     # ['tea', 'coffee', 'cocoa']
print(sum(prices.values()))    # 460

keys(), values() and items() return views, not lists: they look at the live dictionary and reflect changes. If you really need a list, wrap it in list().

Sorting a dictionary gives you a list of pairs, not a dictionary:

top = sorted(prices.items(), key=lambda kv: kv[1], reverse=True)
print(top)        # [('coffee', 250), ('tea', 120), ('cocoa', 90)]
print(dict(top))  # back to a dictionary, if you need one

Changing, deleting, merging#

prices.update({"tea": 130, "juice": 100})
print(prices)   # {'tea': 130, 'coffee': 250, 'cocoa': 90, 'juice': 100}

removed = prices.pop("cocoa")
print(removed)               # 90
print(prices.pop("none", 0)) # 0 instead of KeyError
del prices["juice"]

update overwrites existing keys and adds new ones. Since Python 3.9 there is a merge operator: a | b gives a new dictionary, and a |= b changes a in place. When a key appears in both, the right-hand dictionary wins.

A dictionary comprehension is built like a list comprehension, but with a pair separated by a colon:

squares = {n: n * n for n in range(4)}
print(squares)          # {0: 0, 1: 1, 2: 4, 3: 9}
swapped = {v: k for k, v in squares.items()}
print(swapped[9])       # 3

Where it breaks#

Adding while iterating. Changing the size of a dictionary inside a loop over it raises RuntimeError: dictionary changed size during iteration. Collect the changes separately or iterate over a copy: for k in list(d).

Duplicate keys in a literal. {"a": 1, "a": 2} is not an error — you end up with {'a': 2}: the last assignment silently wins.

True and 1 are the same key. Keys are compared by value, and 1 == True, so {1: "one", True: "yes"} collapses into a single item with the value "yes".

Counting with get. A typical task is counting frequencies. Without a dictionary it grows into a dozen lines; with one it fits in three:

counts = {}
for ch in "abracadabra":
    counts[ch] = counts.get(ch, 0) + 1
print(counts)   # {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}

Try it yourself: count word frequencies in a text and print the three most common using sorted with key. For the text handling you will need Python strings, and when order matters more than keys, use Python lists.

Step-by-step plan

  1. A settings dictionaryCreate a dictionary of five pairs, print a value by key and the length.
  2. Safe accessCompare d["none"] with d.get("none", 0): the first call should raise KeyError.
  3. Iterate with itemsPrint every pair as "key → value" using items().
  4. Character frequenciesCount how many times each character appears in a string using get.
  5. Sort by valueSort the pairs by value in descending order and print the first three.

Start learning this in your own space

The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.

Start the plan

Check yourself

1.What does this print: d = {"a": 1}; print(d.get("b", 0))?

2.What does print(len({"a": 1, "b": 2, "a": 3})) print?

3.What does this print: d = {"x": 1}; print("x" in d, 1 in d)?

4.How many times does the letter "a" appear in the string "abracadabra"?

Sources

Was this helpful?

More articles

Programming and IT Python: lists A list is a mutable, ordered collection of values of any type. It is also the main source of surprises for beginners: assignment does not copy a list, sort returns nothing, and removing items inside a loop skips half of them. Let us go through it in order. Programming and IT Python: strings A string in Python is an immutable sequence of characters. Almost all of its quirks follow from that: methods do not change a string but return a new one, and fast text building goes through join, not through adding strings in a loop. Below is the working minimum with examples and output. Programming and IT How to learn Python from scratch Python is a good first programming language: code reads almost like text, and the standard library covers most everyday tasks. This plan takes you from installing the interpreter to your own scripts covered by tests in about four months, at roughly an hour a day. Programming and IT Python: classes A class describes what data an object is made of and what it can do. The `__init__` constructor fills in a new object, and `self` is a reference to the object itself. Below: a minimal working class, the difference between class and instance attributes, and ways to make the code shorter. Programming and IT Python: functions A function is a named piece of code that takes values and returns a result. In Python a definition takes one line, but arguments have subtleties: defaults are evaluated once, positional and keyword arguments mix by rules, and a function without return still returns something. Programming and IT Python: reading a file Working with a file takes three steps: open it, read or write, close it. You are better off not closing it by hand — that is what the `with` statement is for. And the parameter people forget most is the encoding: without it, the same code reads a file differently on different machines.

More solutions