Python > Core Python Basics > Data Structures > Mutability and Immutability
Understanding Mutability and Immutability in Python
This code snippet demonstrates the concepts of mutability and immutability in Python, using lists and tuples as examples. It highlights how mutable objects can be changed after creation, while immutable objects cannot.
Introduction to Mutability and Immutability
In Python, every variable holds a reference to an object. Objects can be either mutable or immutable. Mutable objects can be changed after they are created. Examples include lists and dictionaries. Immutable objects cannot be changed after they are created. Examples include integers, floats, strings, and tuples. Understanding this distinction is crucial for avoiding unexpected behavior in your code, especially when dealing with shared references.
Demonstrating Mutability with Lists
This code shows how a list, which is mutable, can be modified after its creation. We use the append()
method to add an element and directly assign a new value to an existing element. Each change directly affects the original list object.
my_list = [1, 2, 3]
print(f"Original list: {my_list}")
my_list.append(4)
print(f"List after appending: {my_list}")
my_list[0] = 10
print(f"List after modifying element: {my_list}")
Demonstrating Immutability with Tuples
Tuples are immutable. Attempting to modify an element of a tuple (e.g., my_tuple[0] = 10
) will raise a TypeError
. The code demonstrates how we can effectively "modify" a tuple by creating a brand new tuple object and assigning it to the same variable. This doesn't change the original tuple; it replaces it with a new one.
my_tuple = (1, 2, 3)
print(f"Original tuple: {my_tuple}")
# The following line will raise a TypeError
# my_tuple[0] = 10
my_tuple = (10, 2, 3) # Creating a NEW tuple
print(f"Tuple after 'modifying' by re-assignment: {my_tuple}")
Impact of Mutability on Shared References
This section illustrates the potential side effects of mutability when dealing with shared references. When To avoid this, use the list2 = list1
, both variables point to the same list object in memory. Modifying list1
will therefore affect list2
as well..copy()
method to create a new list object that contains the same elements. In the example list4 = list3.copy()
, list4
and list3
are independent, so modifying one does not affect the other.
list1 = [1, 2, 3]
list2 = list1 # list2 now references the SAME list object as list1
print(f"list1: {list1}")
print(f"list2: {list2}")
list1.append(4)
print(f"list1 after appending to list1: {list1}")
print(f"list2 after appending to list1: {list2}")
list3 = [1, 2, 3]
list4 = list3.copy() # list4 is a NEW list object, a copy of list3
list3.append(4)
print(f"list3 after appending to list3: {list3}")
print(f"list4 after appending to list3: {list4}")
Real-Life Use Case: Configuration Management
Mutable Lists for Dynamic Configurations: Imagine managing server configurations. You might use a list to store allowed ports. Since the allowed ports can change, using a mutable list makes sense. You can easily add or remove ports as needed without creating a new configuration object each time. Immutable Tuples for Secure Configurations: Consider storing cryptographic keys. Since changing a key after deployment poses a significant security risk, using a tuple ensures that the key remains constant throughout the application's lifecycle.
Best Practices
.copy()
for lists or copy.deepcopy()
for more complex objects.
When to use them
Alternatives
Interview Tip
A common interview question is to explain the difference between mutable and immutable objects in Python. Be prepared to provide examples of each and explain the implications of mutability on shared references and function arguments. Mention techniques like .copy()
and copy.deepcopy()
to create independent copies of mutable objects.
FAQ
-
Why are strings immutable in Python?
Strings are immutable for several reasons: Security: Immutable strings prevent unexpected modifications to sensitive data. Performance: Immutability allows for optimizations like string interning (reusing the same string object for identical string literals), which can save memory and improve performance. Hashability: Immutable objects can be used as keys in dictionaries because their hash value remains constant. -
What is the difference between
copy()
anddeepcopy()
?
copy()
creates a shallow copy of an object, meaning it creates a new object but the elements within that object are still references to the original elements.deepcopy()
creates a deep copy, meaning it creates a new object and recursively copies all the objects within it. If the original object contains mutable objects, changes to those objects in the original will be reflected in the shallow copy but not in the deep copy.