Assignment copies the name, not the list
b = a does NOT copy a list. This follows from what assignment has meant since lesson 1-2: it attaches a name to a value, it never duplicates the value. After b = a, both names point to the same list in memory, so a change made through either name is visible through both.
You never noticed this with ints and strings because they are immutable, there is nothing a second name could change. Lists are mutable, so a shared list can be edited out from under you, and that is a classic real-world bug: a second variable, or a function you passed the list to, "mysteriously" modifies your data.
When you genuinely want an independent copy, build one: list(a) (or the slice a[:]) creates a new list containing the same items.
Sharing against copying, side by side
Predict all three printed lists before reading the output. b shares a's list while c is a real copy.
a = [1, 2, 3] b = a b.append(4) print(a) c = list(a) c.append(99) print(a) print(c)
Output
[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 99]
The first print already shows the surprise. Nothing was appended through a, yet a has four items, because b.append(4) modified the single list that both names refer to.
The second and third prints show the contrast. list(a) built a genuinely separate list, so appending 99 through c left a untouched at four items while c has five. The two lists now have independent futures, which is exactly what a backup or a working copy requires.
This snippet prints [1, 2, 3].
x = [1, 2] y = x y.append(3) print(x)
The line y = x did not copy anything. It made y a second name for the same list, so appending through y modified the one list both names refer to, and x sees the change.
Keeping x untouched requires an actual copy, written y = list(x) or y = x[:]. The reason this bug is dangerous in real code is that it is invisible at the point of the mistake: the append looks local and correct, and the damage only surfaces later when some other part of the program reads x and finds data it never modified.
Making a real backup means copying before the change, and using list() rather than a plain assignment.
original = ["read", "code", "sleep"] backup = list(original) original.append("gym") print(original) print(backup)
Output
['read', 'code', 'sleep', 'gym'] ['read', 'code', 'sleep']
The two prints differ, which is the proof that the copy is independent. list(original) built a new list holding the same three items, so the later append reached only the original.
Both parts of the setup matter. Writing backup = original would share instead of copy and both lines would show gym, and copying after the append would preserve the wrong state. A backup that shows the change it was meant to guard against is the signature of having copied the name rather than the list.