ProgrammingBackend Python Developer

What is the difference between shallow copy and simple assignment of a variable? How does copy.copy() work with nested data structures (lists in lists)?

Pass interviews with Hintsage AI assistant

Answer

Variable assignment (for example, a = b) in Python does not copy the object itself but merely creates a new name (reference) to the existing object. Changes through one name will be visible through the other if it is a mutable object.

Shallow copy, for example, through copy.copy(obj) or slicing [:] for a list, creates a new top-level object, but the nested objects inside are copied by reference (i.e., both structures "point" to the same sub-containers). If you modify the nested objects, the changes will be visible through both objects.

Example:

import copy lst1 = [[1,2], [3,4]] lst2 = copy.copy(lst1) # or lst1[:] lst1[0][0] = 100 print(lst2) # [[100, 2], [3, 4]]

lst2 is a new list, but its first element is the same nested list.

Trick Question

Question: What is the difference between lst2 = lst1[:] and lst2 = copy.copy(lst1)?

Answer: In practice, for ordinary (one-level) lists, there is no difference — both methods create a shallow copy of the list. However, for custom container classes, there may be different behaviors (for example, if a custom __copy__ method is implemented). Similarly, for other types (dict, set, etc.), using the specialized copy module is safer.

import copy lst1 = [1, 2, 3] lst2 = lst1[:] lst3 = copy.copy(lst1) print(lst2 == lst3) # True

Examples of Real Errors Due to Ignorance of the Topic


Story

In a project with configuration processing, a developer duplicated default parameters through assignment params = default_params and expected to change them "in isolation." Ultimately, any changes in any copy led to a cascade of changes throughout the application since they were actually working with the same object.


Story

An inexperienced programmer used a shallow copy of a list to store the game state (game_states = states[:]). With a nested structure (lists of pieces on the board), changes inside one state " leaked" into others, breaking the history of rollbacks and move repetitions.


Story

When trying to clone data in an OOP application, the choice was between slicing and copy.copy(). But the structure encountered its own class with its own copy method, which was only considered when using copy.copy(). Slicing ignored the logic of copying the object, leading to non-obvious bugs.