Advanced

Names and values are separate things

A name points at a value rather than containing one. Two names can point at the same value, and that is the whole reason some changes show up in two places and some do not.

What you will see

[1, 2]

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Share one value between two names, then separate them.

1

Point two names at one list.

a = [1, 2] b = a

Before you run it, say out loud what it will print. Then open the answer.

What it prints
>>>
2

Change the list through b and print a. The change shows.

b.append(3) print(a)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
[1, 2, 3]
3

Copy the list so b has its own value, then change b.

a = [1, 2] b = a[:] b.append(3) print(a)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
[1, 2]
4

Re-fill a instead of changing it. b keeps pointing at the old list.

a = [1, 2] b = a a = a + [3] print(b)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
[1, 2]
a + [3] builds a new list and re-points a. b still points at the original, which is why the append form and the plus form behave differently.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Assignment points a name at a value, a change to that value is visible from every name pointing at it, and a copy makes a separate value.
1 a points at the list
↓
2 b points at the same list
↓
3 append changes that list
↓
4 a shows the change too
Why this works
The mental model

Values live in the machine, names are arrows to them. Assignment draws an arrow, and a change to a value is visible from every arrow that points at it. This model explains both the surprise and the fix, and it is the same in every language with this kind of value.

When it bites

Whenever one value is shared, a change through any handle is seen by all of them. That is useful for sharing state, and dangerous when you meant to work on one copy. Saying which one you want, change or copy, is the discipline that prevents the bug.

Examples

Two names, one value

a = 5
b = a
print(a == b)

Both names point at the same 5. Numbers are values that cannot be changed from the inside, so later work on one name never disturbs the other.

A value that can change

a = [1, 2]
b = a
b.append(3)
print(a)

This prints 1, 2 and 3. a and b point at one list, and append changed that list itself. The name b was never needed to make the change visible in a.

Make a copy instead

a = [1, 2]
b = a[:]
b.append(3)
print(a)

The slice copies the list, so b points at its own value. Now changing b leaves a at 1, 2. Copying is the step that separates two handles.

Re-fill versus change

a = [1, 2]
b = a
a = a + [3]
print(b)

Re-filling a points it at a new list; b still points at the old one. Changing a list and pointing a name at a new list are different moves, and only the first reaches the other name.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Names live in a region
Previous Lesson
Names live in a region
Next Lesson
What the machine holds underneath
What the machine holds underneath →