There are two types of objects in Python, Mutable and immutable objects. Mutable objects are more flexible in that these objects can be changed in place. Immutable objects are more static and cannot be changed without allocating a new object of the new type or with the new value.
In some languages, almost all variables are immutable. In other languages most objects are mutable, and you can be fairly liberal with changing the objects whenever you want. Today we will discuss mutable vs immutable objects. How they differ, and which objects are which type.
Which Objects in Python are Immutable?
Some examples of immutable objects are:
- bool
- integer
- float
- tuple
- string
- Frozenset
Which Objects in Python are Mutable?
Some examples of mutable objects are:
- list
- set
- dictionary
How to tell if something is Mutable?
You can tell which objects are mutable by using the type and ID functions. First, we can look at an example of something that is immutable. Let’s run the following code:
string1=“hello” type(string1) id(string1) string1=“how are you?” type(string1) id(string1)
In the code/screenshot above, you can see we declare a string, we then check the type and confirm it is a string. We then used the id function to show the unique identifier for the object. In our case, the ID of our string “hello” was 4548864352. We then changed the value of string1 to “how are you?” and re-ran the id() function, and we got a new identifier of 4548867552. If string1 is immutable, meaning it can’t be changed, how do we explain this?
The variable called string1 is really a pointer to an object. When we create the string “hello”, we are creating an object and pointing the variable called string1 at that object. When we create a new string “how are you?” we are re-pointing our variable to a new object with a new value.
Next, let’s look at a mutable object, a list. We start by declaring our list of fruit:
list1=['orange','apple','pear']
We can then check the type and ensure that it is, in fact, a list:
type(list1)
Then we check the id of our object:
id(list1)
We can now change the list by appending a grape to our list:
list1.append('grape')
If we check our id again, we will see that the id has not changed. This tells us that the object is in fact mutable:
id(list1)
That said, just because it is mutable, does not mean that we can’t get a new object. if we re-declare list1 again, we will get a new list:
list1=['orange','apple','pear','strawberry'] id(list1)
Notice the id for list1 has changed after I re-declared it. What this tells us is we can treat mutable objects as immutable objects if we so choose.
Here is a summary and screenshot of the above code:
list1=['orange','apple','pear'] type(list1) id(list1) list1.append('grape') id(list1) list1=['orange','apple','pear','strawberry'] id(list1)
How is Python different from other languages?
If you use C++ as an example, almost everything is immutable in C++. C++ is a very strongly typed language After you declare a variable as an integer, that variable will stay an integer unless you declare a new data type on a new variable, and convert the original integer into that new data type. There are some methods of getting around this by creating your own class and setting everything as private. But we are not going to get into that today.
In C++, we can declare an int and give it a value:
int myinteger = 5
If we later try to re-declare it as a string, we will get an error:
//can’t do this string myinteger = “Hello!"
Python is not a strongly typed language. This means that in Python, we can do what I have shown above:
myint = 5 Type(myint) myint=“Hello!” Type(myint)
However, just because you can do this, does not mean you should. It can get very confusing if the types of your variables keep changing. It is nice that python gives you lots of flexibility in handling your variables. But having strong types in other languages can help save you from making bad choices.
Why is it important to know about immutable objects?
It is important to know how mutable and immutable objects work so you can write your programs to run efficiently.
For example, lets use string concatenation.
string1 = hello string1 = string1 + “ how are you?” print(string1)
The above code creates a string, appends to the string, then prints it out again. The output will be “hello how are you?”
At first glance, this looks like a single string that is being modified. But, if we use the id() function, on string1 along the way, we will see we actually have two strings:
string1 = hello id(string1) string1 = string1 + “ how are you?” id(string1) print(string1)
Doing this concatenation a single time is not that big of a deal. However, if you have an application doing thousands of these actions it can add up. Every time you do this action you are allocating a new object, and copying the new value into the new object. If you can use mutable objects, you can reduce the amount of time you spend copying stuff within memory, and you can improve the efficiency of your application.
Let’s compare this with a mutable object, a list.
fruit=[] id(fruit) fruit.append('apple') id(fruit) fruit.append('pear') id(fruit) fruit.append('orange') id(fruit) string1 = " ".join(fruit) print(string1)
In the above example, we allocate a list, then append to the list 3 times. Each time we append, we check the id and verify that the id has not changed. This tells us that we are still working with the same object. It is not until the end that we copy everything out into a new string using the join function. This reduces the number of times we have to allocate new objects and copy them within memory. And makes our application that much more efficient.
Summary
We have talked about Mutable and Immutable objects. We have discussed which objects in Python fit into which category. And how Python differs from other languages. By knowing what kind of object you are working with, you can design your application to be more efficient, and more performant.