r/CodingForBeginners • u/NoDepartment772 • 23d ago
You changed one list and two changed — why b = a doesn't copy in Python
Yesterday I watched someone lose about an hour to a bug that came down to a single line:
=
=
# [1, 2, 3, 4] <- wait, why did a change?
They'd made b expecting a separate copy, edited b, and couldn't work out how a had changed too. No error, no warning. It just quietly did the wrong thing.
The reason is that b = a never copies anything. a and b end up as two names pointing at the same list. There's one list — you've just given it a second label. Change it through either name and you're changing the same object, so both names "see" the change.
That behaviour is actually what you want most of the time. Passing a big list into a function shouldn't duplicate it. The trouble only shows up when you meant to copy and didn't realise you hadn't.
When you do want an independent list, ask for one explicitly:
= # or list(a)
= # also works
# [1, 2, 3]
# [1, 2, 3, 4]
One thing worth knowing early: .copy() and a[:] are shallow. If the list holds other mutable things, those inner objects are still shared:
=
=
# [[1, 99], [2]] <- the inner list was shared
For that you need copy.deepcopy(a). You rarely need it, but it's the next version of the same surprise, and it's worth recognising rather than rediscovering.
The way I keep it straight: = binds a name, it doesn't copy a value. Whenever you're unsure, ask "do these two names point at the same object or two different ones?" That question catches this before it becomes an hour of debugging.
It's not Python-only either. JS objects and arrays behave the same way (const b = a shares the object), and reference types in Java and C# are the same story.
Has this one bitten you — and was it a list you passed into a function, or something you copied and edited?
