Python Mutable vs Immutable Objects Explained

Short answer
Mutable objects (list, dict, set) can be changed in place after creation, while immutable objects (int, float, str, tuple, bool, frozenset) cannot; "changing" an immutable value really creates a new object.

Every value in Python is an object, and every object is either mutable or immutable. This decides whether a method like append() can modify the object where it sits, or whether any change has to produce a brand-new object.

Understanding the difference explains several confusing behaviours: why text.upper() does not change text, why two variables can unexpectedly share one list, and why a list cannot be a dictionary key. It also affects how function arguments behave.

Python
name = "asha"
name.upper()
print(name)
items = [1, 2]
items.append(3)
print(items)

Mutable vs immutable types in Python

AspectMutableImmutable
Built-in typeslist, dict, set, bytearrayint, float, bool, str, tuple, frozenset, bytes, None
Can change in place?YesNo
What += doesUsually modifies the same object (for a list)Creates a new object and rebinds the name
Hashable?No, so not usable as dictionary keys or set itemsYes (for a tuple, only if all its items are hashable)
Safe to share between variables?Risky: a change shows through every nameSafe: nobody can modify it
Example methodmy_list.sort() changes the listmy_str.upper() returns a new string

What happens when you assign a mutable object to a second name

Assignment never copies an object. b = a makes both names point to the same object. With an immutable value that is harmless, because the object can never change. With a mutable one, a change made through b is visible through a. Use a.copy() or list(a) to get an independent list; see copying lists and dictionaries.

When to use mutable objects

Use mutable types when the data is built up or edited over time.

  • Collecting results in a list inside a loop.
  • Counting with a dictionary.
  • Keeping a running collection of unique items in a set.

Mutating in place avoids creating a new object each time, which is efficient for large collections.

When to use immutable objects

Use immutable types when the value should stay fixed.

  • Keys for dictionaries and members of sets must be hashable, which in practice means immutable.
  • Constants and configuration, for example a tuple of allowed options.
  • Default values for function parameters. A mutable default such as def add(item, bag=[]) is shared between calls and is a classic bug; use None and create the list inside the function.

Strings are immutable too, which is why building a large string by repeated += in a loop is slower than collecting pieces and calling "".join(pieces).

Examples you can run

Press Run, then edit the code and run it again.

Two names, one list

backup is not a copy; it is a second name for the same list, so the change shows in both.

Two names, one list
cart = ["pen"]
backup = cart
cart.append("book")
print(backup)
print(cart is backup)
Expected output['pen', 'book']
True

Immutable values are rebound, not changed

+= on an integer creates a new integer, so the other name keeps the old value.

Immutable values are rebound, not changed
a = 10
b = a
a += 5
print(a, b)
Expected output15 10

A string cannot be edited in place

Assigning to a character raises TypeError; build a new string with a method instead.

A string cannot be edited in place
word = "cat"
try:
    word[0] = "b"
except TypeError as error:
    print(error)
word = "b" + word[1:]
print(word)
Expected output'str' object does not support item assignment
bat

Common mistakes

Mutable default argument

✗ Wrong

def add_item(item, bag=[]):
    bag.append(item)
    return bag

print(add_item("pen"))
print(add_item("book"))
['pen'] ['pen', 'book'] (the default list is shared between calls)

✓ Right

def add_item(item, bag=None):
    if bag is None:
        bag = []
    bag.append(item)
    return bag

print(add_item("pen"))
print(add_item("book"))

Use None as the default and create a fresh list inside the function.

Expecting a string method to change the string

✗ Wrong

title = "python"
title.upper()
print(title)
python

✓ Right

title = "python"
title = title.upper()
print(title)

String methods return a new string. Assign the result back to a name.

Python Mutable vs Immutable Objects Explained: questions people ask

Is a tuple mutable or immutable in Python?

A tuple is immutable: you cannot add, remove or replace its items. If it contains a mutable object such as a list, that inner object can still change.

Why are strings immutable in Python?

Immutability makes strings safe to share, lets them be hashed for dictionary keys and allows Python to reuse them. Operations such as replace() return a new string instead of editing the old one.

How can I tell if a type is mutable?

Try changing it in place, for example with item assignment or append(). A quick rule: list, dict and set are mutable; numbers, strings, tuples and booleans are not.

Keep learning

Step-by-step lessons:
Python Data TypesCopying Lists and DictsPython Variables

Related:
Python List vs Tuple: Differences and When to Use EachPython Deep Copy vs Shallow Copy: What Is the Difference?Python is vs == Operator: What Is the Difference?Python List copy() Method

More in data types and structures:
Python List vs Tuple: Differences and When to Use EachPython List vs Set: Differences and When to Use EachPython List vs Dictionary: Differences and When to Use Each See all →