Review

Reconstruct the path from meaningful lookup through keyed counts and groups to set membership, shared objects, and deliberate outer copies.

From a Label to Its Value

A dictionary connects each key to one value. The key states how the program will find the value again:

Use brackets when the key is required. A missing required key is evidence that the data does not satisfy the program's expectation. Use .get only when the fallback is a truthful result, such as zero previous occurrences:

counts[label] = counts.get(label, 0) + 1

Dictionary membership asks about keys. Assigning a new key adds a pair; assigning an existing key replaces its value.

From Repeated Labels to Counts or Groups

A count stores one number under each key. A group stores a collection of the values that arrived with that key.

These loops answer different questions. counts["north"] says how many north readings occurred. groups["north"] keeps the readings themselves. Do not use a comprehension to hide repeated-key grouping: assigning the same generated key again would replace its earlier value.

Plain dictionary iteration visits keys. .values() visits values, and .items() supplies key-value pairs for unpacking. Dictionaries preserve insertion order, but a report that promises a particular order should state it with sorted.

From Presence to a Set

A set is useful when the question is whether a label occurs, not how often it occurs or which readings belong to it:

Repeated additions leave one set member. Sets do not provide a meaningful display order, so sort them when order is part of the output.

From Two Names to One Object

Assignment does not copy a mutable collection:

Both names refer to the same list, so both show [18, 21, 20]. The two names are aliases. Reassigning working to another list changes the connection for that name; it does not change original.

== asks whether values are equal. is asks whether two references identify the same object. Use value equality for ordinary comparisons and reserve identity checks for questions that truly concern the object, especially value is None.

From an Alias to a Deliberate Copy

.copy() creates a new outer list, dictionary, or set. Changes to a flat copy do not change the original outer collection:

Here original["north"] remains 18. A shallow copy does not recursively copy nested mutable values:

The two outer dictionaries are different, but both still refer to the same inner list. Both therefore show the appended reading. A useful function states its ownership choice: either it deliberately mutates the supplied collection, or it makes the required copies and returns the changed result.

The complete path is:

meaningful key → lookup → count or group → membership set
               → shared object → deliberate outer copy

Pause and reflect

What can you now explain without looking back, and what should you revisit? The note stays with this review.

Review

Not marked done.