Immutable vs Mutable types
What? Floats are immutable? But can't I do
x = 5.0x += 7.0print x # 12.0
Doesn't that "mut" x?
Well you agree strings are immutable right? But you can do the same thing.
s = 'foo's += 'bar'print s # foobar
The value of the variable changes, but it changes by changing what the variable refers to. A mutable type can change that way, and it can also change "in place".
Here is the difference.
x = something # immutable typeprint xfunc(x)print x # prints the same thingx = something # mutable typeprint xfunc(x)print x # might print something differentx = something # immutable typey = xprint x# some statement that operates on yprint x # prints the same thingx = something # mutable typey = xprint x# some statement that operates on yprint x # might print something different
Concrete examples
x = 'foo'y = xprint x # fooy += 'bar'print x # foox = [1, 2, 3]y = xprint x # [1, 2, 3]y += [3, 2, 1]print x # [1, 2, 3, 3, 2, 1]def func(val): val += 'bar'x = 'foo'print x # foofunc(x)print x # foodef func(val): val += [3, 2, 1]x = [1, 2, 3]print x # [1, 2, 3]func(x)print x # [1, 2, 3, 3, 2, 1]
You have to understand that Python represents all its data as objects. Some of these objects like lists and dictionaries are mutable, meaning you can change their content without changing their identity. Other objects like integers, floats, strings and tuples are objects that can not be changed.An easy way to understand that is if you have a look at an objects ID.
Below you see a string that is immutable. You can not change its content. It will raise a TypeError
if you try to change it. Also, if we assign new content, a new object is created instead of the contents being modified.
>>> s = "abc">>> id(s)4702124>>> s[0] 'a'>>> s[0] = "o"Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'str' object does not support item assignment>>> s = "xyz">>> id(s)4800100>>> s += "uvw">>> id(s)4800500
You can do that with a list and it will not change the objects identity
>>> i = [1,2,3]>>> id(i)2146718700>>> i[0] 1>>> i[0] = 7>>> id(i)2146718700
To read more about Python's data model you could have a look at the Python language reference:
Common immutable type:
- numbers:
int()
,float()
,complex()
- immutable sequences:
str()
,tuple()
,frozenset()
,bytes()
Common mutable type (almost everything else):
- mutable sequences:
list()
,bytearray()
- set type:
set()
- mapping type:
dict()
- classes, class instances
- etc.
One trick to quickly test if a type is mutable or not, is to use id()
built-in function.
Examples, using on integer,
>>> i = 1>>> id(i)***704>>> i += 1>>> i2>>> id(i)***736 (different from ***704)
using on list,
>>> a = [1]>>> id(a)***416>>> a.append(2)>>> a[1, 2]>>> id(a)***416 (same with the above id)