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.
Give related results meaningful names
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.