ReviseAlgo Logo

Lists

Copying Lists

Shallow vs deep copy

Interview: Common interview trap — tests understanding of Python object references and mutability

Last Updated: June 12, 2026 8 min read

Python variables are references to objects, not the objects themselves. Assigning a list to a new variable doesn't copy it — both variables point to the same object. Understanding shallow vs deep copying is essential for avoiding subtle bugs.

Assignment is NOT a Copy

  • b = a — both names point to the same list object
  • a is b returns True (same identity)
  • Modifying through either name affects the same underlying list
  • Use id(a) == id(b) to verify they're the same object

Shallow Copy Methods

  • lst.copy(): Most readable — built-in method
  • lst[:]: Slice copy — idiomatic Python
  • list(lst): Constructor copy
  • copy.copy(lst): From the copy module
  • All create a new outer list, but inner mutable objects are still shared references

Deep Copy

  • copy.deepcopy(lst): Recursively copies ALL nested objects
  • Necessary when lists contain mutable objects (other lists, dicts, etc.)
  • Slower than shallow copy — use only when needed
  • Handles circular references correctly

Rule of Thumb

If your list contains only immutable objects (numbers, strings, tuples), shallow copy is fine. If it contains mutable objects (lists, dicts, sets), use copy.deepcopy() to avoid shared reference bugs.

Use Cases

Defensive copying before passing lists to functions that mutate

Implementing undo/redo with state snapshots

Creating independent copies for parallel modification

Snapshot-based testing and comparison

Common Mistakes

Using b = a thinking it creates a copy — it creates a new reference to the same object

Using shallow copy for nested mutable structures — inner objects are still shared

Using deepcopy everywhere when shallow copy suffices (for flat lists of immutables)

Not knowing that function parameters are passed by reference — mutations affect the caller