Get AI summaries of any video or article — Sign up free
Programming Terms: Mutable vs Immutable thumbnail

Programming Terms: Mutable vs Immutable

Corey Schafer·
4 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Strings are immutable in Python, so character-level edits by index raise errors rather than modifying existing content.

Briefing

Mutable vs. immutable is a practical distinction about whether an object’s contents can change after creation—and it directly affects both correctness and performance. In Python, strings are immutable: once a string object is created, its characters can’t be altered in place. Reassigning a variable to a new value doesn’t “modify” the original string; it creates a brand-new string object. That’s why changing a variable from “Corey” to “John” works, yet attempting to change a single character inside the string raises a TypeError (“string object does not support item assignment”).

Python’s memory behavior makes the difference concrete. Using Python’s id() function to print memory addresses shows that after reassignment, the string’s address changes—evidence that a new object was created. When trying to mutate a character (for example, uppercasing the first letter by indexing), Python blocks the operation because the existing string object cannot be edited. By contrast, lists are mutable. If a list like [1, 2, 3, 4, 5] is updated by changing an element (e.g., setting index 0 to 6), the list updates “in place.” The id() value stays the same, reflecting that the same object was modified rather than replaced.

The performance implications are where the distinction becomes more than a definition. Repeatedly building up a large string by concatenation can look harmless at small scale, but it can become expensive when done thousands of times. The transcript’s example uses a loop that constructs HTML output by repeatedly appending employee data to a single output variable. Because strings are immutable, each concatenation step produces a new string object. If the loop runs many times, the program allocates thousands of new string objects in memory, increasing overhead and slowing execution.

The fix is to use a mutable structure for incremental building. In Java, the same principle applies: String is immutable, while StringBuffer is mutable and designed for efficient concatenation. Using a mutable buffer avoids the repeated creation of new string objects during large concatenation tasks. In short, knowing whether an object is mutable or immutable helps prevent runtime errors (like trying to edit a string by index) and helps avoid hidden performance costs from repeated allocations during string construction.

Cornell Notes

Mutable objects can be changed after creation; immutable objects cannot. In Python, strings are immutable, so changing a variable to a new string creates a new object (different id()), while attempting to modify a character by index raises a TypeError. Lists are mutable, so updating an element changes the same object in place (same id()). This matters for performance: repeated string concatenation in a loop creates many new string objects because each concatenation must produce a fresh immutable string. For heavy concatenation, use a mutable alternative such as Java’s StringBuffer to reduce allocation overhead.

Why does reassigning a Python string variable work even though strings are immutable?

Immutability prevents editing the existing string object’s contents. When a variable like a is reassigned from “Corey” to “John,” Python doesn’t modify the original string; it creates a new string object and points the variable to it. Using id(a) before and after reassignment shows different memory addresses, confirming a new object was created.

What happens when code tries to change a single character in a Python string?

Attempting item assignment on a string by index (for example, trying to uppercase the character at index 0) fails because the string object can’t be modified in place. Python raises a TypeError stating that the string object does not support item assignment.

How can id() demonstrate the difference between immutable strings and mutable lists?

Printing id() for a string before and after reassignment shows the address changes, indicating a new object was created. For a list, updating an element (like setting index 0 to 6) keeps the id() the same, showing the list was modified in place rather than replaced.

Why is repeated string concatenation in a loop a performance problem?

Each concatenation step must produce a new string because strings are immutable. In a loop that runs many times (e.g., thousands of employees), the program allocates thousands of new string objects and discards the old ones. The transcript’s example even shows changing id(output) inside the loop to illustrate that a new string object is created each iteration.

What’s the practical alternative for large concatenation tasks in Java?

Java’s String is immutable, so heavy concatenation can suffer from repeated allocations. Java’s StringBuffer is mutable and intended for efficient incremental building, avoiding the performance hit of creating thousands of new String objects during concatenation.

Review Questions

  1. In Python, what evidence would you look for (id values or error behavior) to confirm whether a type is immutable?
  2. How does repeated concatenation change memory allocation patterns when the concatenated type is immutable?
  3. When would you choose a mutable buffer approach over straightforward concatenation in a loop?

Key Points

  1. 1

    Strings are immutable in Python, so character-level edits by index raise errors rather than modifying existing content.

  2. 2

    Reassigning a string variable creates a new string object; id() changes because the original object remains unchanged.

  3. 3

    Lists are mutable in Python, so element updates modify the same object in place; id() stays the same.

  4. 4

    Repeated string concatenation in loops can cause significant performance and memory overhead by allocating many new string objects.

  5. 5

    For large concatenation workloads, use a mutable builder/buffer approach (e.g., Java’s StringBuffer) to reduce allocations.

  6. 6

    The mutable vs. immutable distinction helps prevent both runtime errors and hidden inefficiencies.

Highlights

Trying to uppercase a character inside a Python string by index triggers a TypeError because strings don’t support item assignment.
Using id() reveals that string reassignment produces a new object (different memory address), while list element updates keep the same object (same memory address).
Building large HTML output via repeated string concatenation in a loop creates a new string object on every iteration, which becomes costly at scale.
In Java, StringBuffer serves the same role as a mutable alternative to immutable String for efficient concatenation.

Topics

Mentioned