Foundations: Python, Git and toolsLoading progress…

Dictionaries and lookup

Write a small program that transforms data using conditions, loops and functions.

Look things up by meaning, not by position

Suppose you store two scores in a list: [8, 5]. Whose scores are they? You would have to remember that position 0 is Ada and position 1 is Lin. Add a third person in the middle and every position after it shifts. A dictionary stores key: value pairs, so the meaning travels with the data.

scores_list = [8, 5]                 # who is index 1?
scores = {"Ada": 8, "Lin": 5}        # scores["Lin"] is 5, whatever the order

Keys are unique: assigning to a key that already exists replaces its value, and writing a new key adds an entry. {"Ada": 8, "Ada": 9} ends up with one entry, Ada: 9.

Three ways to ask, three behaviours

scores = {...}

"Ada":8
"Lin":5
"Sam":9

scores["Ada"]

gives 8

Keys must match exactly, so "ada" is a different key from "Ada". Looking up a missing key with brackets is an error, while .get and in never fail.

Choose a key and a method. Try Omar, who is not in the dictionary, with each of the three methods.
  • scores[key] is the strict way. A missing key raises KeyError, which is useful when a missing key means your data is wrong.
  • scores.get(key, default) never fails. It returns the default (or None if you give none) and does not add the key.
  • key in scores answers True or False and tests the keys, not the values.

Check yourself first

Predict first. What does scores.get("Omar") give when Omar is missing and you pass no default?

Predict first. An inventory is {"pears": 0}. Is "pears" in inventory true?

The common mistake

scores = {"Ada": 8, "Lin": 5}
print(scores["Omar"])
# KeyError: 'Omar'

The fix is to decide what a missing key should mean: use .get with a default, test with in first, or let the error stop the program when it signals a real bug. Do not invent data by writing scores["Omar"] = 0 just to silence the error.

Chapter context

A program is a precise sequence of state changes. Python names refer to objects; reading a program means tracking the values those names refer to, rather than guessing from how the code sounds.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

For an accumulator over numbers x1,…,xnx_1,\ldots,x_n:

s0=0,si=si−1+xi.s_0=0,\qquad s_i=s_{i-1}+x_i.

The subscript denotes a step, not a Python index. After the last step, sns_n is the sum. For a mean, divide by the number of items, and define what should happen for an empty list.

Worked example

Trace a robot's forward distances [2, 1, 3]. Position starts at zero and changes to 2, then 3, then 6. Replacing three copy-pasted moves with a loop preserves the order and final state. A mean distance is 6/3 = 2; the count is 3, not the last list index 2.

Reference code

The following example uses the Python standard library and does not call a remote service.

moves = [2, 1, 3]
position = 0
for distance in moves:
    position += distance
assert position == 6
assert sum(moves) / len(moves) == 2

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Assignment does not copy a mutable object. A loop stop value is exclusive. A function can return None even when its print output looks correct.