See When Two Names Share One Collection
Draw names and mutable objects separately so aliases, mutation, reassignment, function parameters, equality, and identity remain predictable.
Lists, dictionaries, and sets can change after they are created. To predict a change, we need to track both the names in the program and the collection each name refers to.
Two Names Can Refer to One List
The second assignment does not create another list. It gives the existing list another name. The two names are aliases:
original ──┐
├──> list A: ["north", "east"]
working ──┘
Changing list A through either name is visible through both names:
There is only one list, and both names lead to it.
| Step | original refers to | working refers to | List A |
|---|---|---|---|
after original = [...] | A | — | [north, east] |
after working = original | A | A | [north, east] |
after working.append("west") | A | A | [north, east, west] |
Q1. Trace an alias and a reassignment
What does this program display?
Select one choice, then check.
HintDraw the two steps separately
First change the shared list. Then move only the name on the left side of the final assignment.
SolutionMutation is shared; reassignment is not
The append changes list A to [18, 21, 20]. Then working = [99] creates
list B and makes only working refer to it. The output is [18, 21, 20]
followed by [99].
Reassignment Moves One Name
Mutation changes an object. Reassignment changes which object a name refers to:
working = ["north", "east"]
After this assignment, the earlier list still exists through original, while
working refers to a new list:
original ─────> list A: ["north", "east", "west"]
working ─────> list B: ["north", "east"]
Changing list B now has no effect on list A. The distinction is not which name looks more important. It is whether the operation mutates an existing object or makes a name refer to another object.
A Function Parameter Is Another Name during the Call
When a function receives a list, its parameter refers to the same list supplied by the caller:
During the call, sensor_labels and labels refer to the same list. The
function mutates that list with append, so the caller sees the change. Calling
a function does not copy a mutable argument automatically.
The parameter name exists only while the function call is active. The changed list remains afterward because the caller's name still refers to it.
Q2. Make the caller-visible change
Complete the function so the program displays ['north', 'east', 'west'].
Editable Python
Ready to run.
HintMutate the received list
Call append on sensor_labels inside the function.
SolutionAppend through the parameter
During the call, that parameter leads to the same list as labels.
Equality and Identity Answer Different Questions
The equality operator == asks whether values have equal contents. The
identity operator is asks whether two names refer to the same object:
left and right are two lists with equal contents. alias is another name
for the list referred to by left.
Use == for ordinary value comparison. Do not replace it with is when
comparing numbers or text. A common deliberate identity check is is None:
Here the program asks whether reading refers to the single None object.
This is the narrow identity check already used by the measurement program.
Q3. Separate equality from identity
Which sequence of results is correct?
Select one choice, then check.
HintDraw two list objects
Let first and same point to one list, and let second point to another
list with the same contents.
SolutionEqual values need not be one object
first == second is True because their contents match. first is second
is False because they are separate lists. first is same is True because
assignment gave the first list another name.
Names and mutable objects must be traced separately. Assignment can create an alias, mutation is visible through every alias, and reassignment moves only one name. A function parameter can also share the caller's object. The next lesson creates a new outer collection deliberately and checks what remains shared inside it.