Skip to main content

Collections and Data Models

What this concept is​

A list stores an ordered sequence and can contain duplicates. A dictionary maps keys to values. A set stores unique members, so it would lose repeated sessions. Choose a representation based on what the values mean.

Why it matters here​

We need an ordered history and a named summary. Their shapes should remain understandable when passed between functions.

Concrete example​

sessions = [25, 15, 25]
report = {"count": len(sessions), "total": 65, "longest": 25}
print(sessions[0])
print(report["total"])
copy_of_sessions = sessions.copy()
copy_of_sessions.append(10)
assert len(sessions) == 3

List indexes start at zero. Dictionary lookups use a key, not a position. This shallow copy is sufficient for a flat list of integers.

Read and update a small list​

sessions = [10, 30, 10]
assert len(sessions) == 3
assert sessions[0] == 10
assert sessions[1] == 30
assert sessions[-1] == 10
assert sessions[:2] == [10, 30]
sessions.append(20)
assert sessions == [10, 30, 10, 20]
assert 30 in sessions

Index 0 means the first item; index 1 means the second. With three items the last nonnegative index is 2. [-1] accesses the last item, but an empty list has no last item. A slice such as [:2] creates a list of the items before index 2; the stop is excluded. len asks how many items exist; in asks whether a value is present.

append changes the list in place and returns None. Write sessions.append(20), not sessions = sessions.append(20): the latter would rebind your name to None. For a simple traversal, use for minutes in sessions; you usually do not need to calculate indexes yourself.

Two names can refer to one object​

original = [10, 20]
alias = original
separate = original.copy()
alias.append(30)
assert original == [10, 20, 30]
assert separate == [10, 20]

Assignment did not duplicate the list. alias and original refer to the same mutable object, so a change through either name is visible through both. separate refers to a new list. Integers in the flat list do not need further copying. A list of lists needs more care: a shallow copy still shares its inner lists. We keep the tracker flat so you can reason about its changes precisely.

A dictionary lets a caller read report["total"] instead of remembering that “item 1 means total.” Keys are unique: assigning a new value to report["total"] replaces that key's old value. A list preserves repeated sessions; a dictionary of summary fields names the calculated results. Neither representation replaces the other.

The example report above writes 65 by hand to show the shape. Your real summary must compute the total from its input. Otherwise it would return a plausible but incorrect constant when the sessions change. For an empty tracker history, our chosen summary is {"count": 0, "total": 0, "longest": 0}. That longest convention works because valid sessions are positive; it is not a universal convention for all data sets.

Common confusion / misconception​

other = sessions creates another name for the same list. other.append(10) then changes the list visible through both names. A missing dictionary key raises KeyError; indexing an empty list raises IndexError. Do not use a set merely to remove inconvenient duplicates.

How to use it​

Document data shapes: history is a list of valid integer minutes; summary is a fresh dictionary with count, total and longest. Have summary computation leave its input unchanged.

Check yourself​

If the data is [20, 20], should count be 1 or 2? Answer: 2. Explain why a set would violate the model.

Mini drill or application​

Write a summary for [10, 30, 10] and [] on paper. Then implement it. Verify that the input list still equals its original value afterward.

Read this only if stuck​

Official source: Python tutorial. Read only the matching section after attempting the example. These lessons and exercises are original curriculum material.