Python's Mutation Minefield: Why Adding Two Numbers Isn't Always the Same Thing

Post date: April 1, 2026 · Discovered: April 23, 2026 · 6 posts, 62 comments

The core confusion centers on Python's data model, specifically the divergent behaviors of `+` versus `+=` operations when handling mutable versus immutable types. Observers note that the addition operator (`__add__`) constructs a new object, while the augmented assignment operator (`__iadd__`) modifies the object in place.

Opinions diverge on the best way to grasp this concept. Some insist the distinction between `a += b` and `a = a + b` is a fundamental misunderstanding if not grasped, as stated by 'kibiz0r'. Others push for a total conceptual pivot toward functional programming principles. Specific pitfalls cited include the danger of modifying mutable default arguments, a trap pointed out by 'sukhmel'. Furthermore, the system's pre-allocation of small integers and short strings creates misleading `id()` values, a point clarified by 'vonbaronhans'.

The inescapable takeaway is that the difference between object creation and in-place modification demands rigorous focus. While consensus agrees that memory visualization tools are helpful, the fault line remains over whether the required mental model should be pointer-based or purely functional. Explicit deep copying, as shown by 'logging_strict', demonstrates where assumptions break down.

Key Points

#1The operational difference between compound assignment and re-assignment is critical.

'kibiz0r' stressed that failing to treat `a += b` and `a = a + b` differently shows a fundamental misunderstanding of the model.

#2Python distinguishes between creating new objects and modifying existing ones.

'bterwijn' noted that `__add__` builds new objects, while `__iadd__` mutates the existing ones, though this is consistent for immutable types.

#3The inherent risk of using mutable default arguments must be avoided.

'sukhmel' highlighted the common pitfall demonstrated by `def fun(a = []):`.

#4Using `id()` for object comparison is unreliable in general practice.

'vonbaronhans' explained that small integers and short strings are 'interned,' leading to deceptively consistent `id()` values.

#5Deep copying is sometimes the only guarantee against accidental mutation.

'logging_strict' argued that explicit copying via `copy.deepcopy()` is necessary to prevent unexpected mutations across variable assignments.

Source Discussions (6)

This report was synthesized from the following Lemmy discussions, ranked by community score.

53
points
Python Mutability
[email protected]·20 comments·9/2/2025·by bterwijn·programming.dev
33
points
Python's Data Model Explained through Visualization
[email protected]·15 comments·4/1/2026·by bterwijn·programming.dev
21
points
Python Mutability
[email protected]·6 comments·10/23/2025·by bterwijn·programming.dev
14
points
Python Data Model: Copying
[email protected]·8 comments·11/14/2025·by bterwijn·programming.dev
14
points
Python Copies
[email protected]·5 comments·10/30/2025·by bterwijn·programming.dev
14
points
Right Mental Model for Python Data
[email protected]·8 comments·10/9/2025·by bterwijn·programming.dev