Playground / Shallow vs Deep Copies of Nested Lists

Copy a nested list, change it, see what's shared

Shallow vs Deep Copies of Nested Lists

Interactive lab

Try it: Shallow vs Deep Copies of Nested Lists

Why b = a copies nothing, why a[:], list(a) and a.copy() copy only the outer list (the inner lists stay shared, so a[0] is b[0]), and how copy.deepcopy copies every level — checked with is and ==.

How it works

  1. b = a binds a second name to the same list object: a is b.
  2. a[:], list(a) and a.copy() make one new outer list whose slots copy the references: a is not b, but a[0] is b[0].
  3. copy.deepcopy copies every list recursively (a memo keeps a list that appears twice as one copy); ints are immutable and simply shared.
  4. Mutating a list reachable from both names (append, item assignment) is seen through both; rebinding a name changes only that name.
  5. is compares identity; == compares values item by item.

Default run (9 steps): The program builds a nested list, copies it one way, then changes one of the two names. … Done. a = [[1, 2, 9], [3, 4]] | b = [[1, 2, 9], 7] | a is b False | a == b False | a[0] is b[0] True

Simplified: Small nested lists of ints; the list numbers L1, L2… stand in for identities (not real id() values). Equal small ints are one cached object in CPython, so a[0] is b[0] can be True for ints.

Educational simulation

Loading the simulation…