Foundational Data Structures~25 min

Lists and Dictionaries

Choose between a list and a dictionary by asking whether data is accessed by position or looked up by a meaningful key.

By the end of this lesson, you can

  • Choose between a list and a dictionary based on whether data needs to be accessed by position or by key
  • Perform basic operations on each — indexing and appending a list, looking up and adding to a dictionary
  • Trace how a list or dictionary's contents change as items are added

Why it matters

Almost every program needs to hold onto more than one value at a time. Python offers several ways to do that, and choosing the right one is a real design decision: a list and a dictionary model information differently, and picking the wrong one makes later code awkward or fragile.

Mental model

Ask one question first: is this data naturally accessed by position, or by a meaningful name?

  • A list is an ordered collection, accessed by numeric index — good when order matters or “the first item” / “the next item” makes sense.
  • A dictionary maps keys to values, accessed by key — good when you think in terms of “look up X’s value,” and the key is more meaningful than its position.

A shopping list is naturally a list — order matters, and you don’t think of “milk” as item number 2. A price lookup is naturally a dictionary — you want the price for an item, not the item at position 2.

Small example

PythonA list: ordered, accessed by position
shopping_list = ["milk", "eggs", "bread"]
print(shopping_list[0])

shopping_list.append("butter")
print(shopping_list)
Output
milk
['milk', 'eggs', 'bread', 'butter']
PythonA dictionary: accessed by key
prices = {"milk": 3.50, "eggs": 2.80, "bread": 4.00}
print(prices["eggs"])

prices["butter"] = 3.20
print(prices)
Output
2.8
{'milk': 3.5, 'eggs': 2.8, 'bread': 4.0, 'butter': 3.2}

shopping_list[0] asks “what’s at position 0?” prices["eggs"] asks “what’s the value for the key "eggs"?” — a completely different question, and Python needs a different structure to answer it well.

Trace it

How each structure's contents change
Operationshopping_listprices
start['milk', 'eggs', 'bread']{'milk': 3.50, 'eggs': 2.80, 'bread': 4.00}
shopping_list.append("butter")['milk', 'eggs', 'bread', 'butter'](unchanged)
prices["butter"] = 3.20(unchanged){..., 'butter': 3.20}

append always adds to the end of a list; assigning to a new dictionary key adds that key without disturbing the others.

Check your understanding

You need to store a leaderboard where position matters (1st place, 2nd place, ...). Which structure fits better?
Or reveal the answer without checking

Answer:A list, since order matters and you access entries by position
Since the data is fundamentally about order (1st, 2nd, 3rd...), a list — accessed by position — models it directly. A dictionary would need you to invent keys like 1, 2, 3 just to fake what a list already does.

What happens when you look up a dictionary key that doesn't exist, using prices[key]?
Or reveal the answer without checking

Answer:It raises a KeyError
Square-bracket lookup on a missing key raises a KeyError immediately — just like an out-of-range list index raises an IndexError. Use .get() if a missing key should produce a fallback instead of an error.

Practice: warm-up

For each scenario, decide whether a list or a dictionary fits better, and say why: (1) the order finishers crossed a race, (2) a student’s ID number mapped to their name, (3) the days of the week in order.

Stuck? Reveal one hint at a time.

  1. Hint 1

    Ask: is the natural way to look something up "by position" or "by a name/ID"?

  2. Hint 2

    Order of finish and days of the week are both fundamentally about sequence.

Reveal the reasoning

Try the problem yourself before reading this. There is often more than one reasonable approach — treat this as one worked example, not the only correct answer.

1. Race finishers   -> list       (order is the whole point)
2. ID -> name lookup -> dictionary (looked up by a meaningful key, not position)
3. Days of the week  -> list       (a fixed, meaningful order)

Practice: apply it

This code is supposed to look up a customer’s loyalty points, defaulting to 0 if they’re not a member yet, but it crashes for new customers:

points = {"ada": 120, "grace": 340}
customer = "linus"
print(points[customer])
What happens when this runs?
Or reveal the answer without checking

Answer:Raises a KeyError
"linus" is not a key in points, so points[customer] raises a KeyError rather than assuming a default.

Modification challenge: fix this using points.get(customer, 0) so new customers correctly show 0 points instead of crashing.

Summary

  • Choose a list when data is naturally ordered and accessed by position; choose a dictionary when it’s naturally looked up by a meaningful key.
  • list.append(item) adds to the end; dict[key] = value adds or updates that key without disturbing the others.
  • A missing list index raises IndexError; a missing dictionary key raises KeyError — both are runtime errors, not silent failures.
  • dict.get(key, default) returns a fallback instead of raising KeyError, for when a missing key is expected rather than a bug.