Mutable vs. Immutable¶
Let’s look at two more examples:
>>> str1 = "hello"
>>> str2 = str1
>>> str2 += " world"
What values are str1 and str2 assigned to?
>>> str1
'hello'
>>> str2
'hello world'
That’s not too surprising. Let’s do the same with lists:
>>> list1 = ["hello"]
>>> list2 = list1
>>> list2 += [" world"]
>>> list1
['hello', ' world']
>>> list2
['hello', ' world']
Wait. What happened??
After initializing the strings and lists the situation is:
![digraph first {
rankdir=LR;
hello [label = "hello", style=dotted, shape=polygon];
"str1" -> hello [weight=100];
"str2" -> hello;
}](../../_images/graphviz-38fc18a820029d82d32b2c366fe6c521046346a1.png)
![digraph first {
rankdir=LR;
hello [label = "[\"hello\"]", style=dotted, shape=polygon];
"list1" -> hello [weight=100];
"list2" -> hello;
}](../../_images/graphviz-4ac02c5d889ffba3a8cd7a2decbceaf75c1176bf.png)
Where’s the difference then??
1) Strings are immutable objects.
Executing
>>> str2 += " world"
![digraph first {
rankdir=LR;
hello [label = "hello", style=dotted, shape=polygon];
helloworld [label = "hello world", style=dotted, shape=polygon];
"str2" -> helloworld;
"str1" -> hello;
}](../../_images/graphviz-a133fe0b570afec5f112e8a65c078aca55e099b1.png)
creates a new string!
2) Lists are mutable objects. This means that a list can be modified:
>>> list2 += [" world"]
does not create a new list! The list is modified in place. Therefore both the names list1 and list2 still have the same value.
![digraph first {
rankdir=LR;
hello [label = "[\"hello\", \" world\"]", style=dotted, shape=polygon];
"list1" -> hello [weight=100];
"list2" -> hello;
}](../../_images/graphviz-862dae69045e576037e22b9ea654a60742aa4736.png)
However:
>>> list1 = ["hello"]
>>> list2 = list1
>>> list2 = list2 + [" world"]
>>> list1
['hello']
>>> list2
['hello', ' world']
does create a new list.
![digraph first {
rankdir=LR;
hello [label = "[\"hello\"]", style=dotted, shape=polygon];
helloworld [label = "[\"hello\", \" world\"]", style=dotted, shape=polygon];
"list1" -> hello [weight=100];
"list2" -> helloworld;
}](../../_images/graphviz-957c1187b7a0cf18ade46f7392e2d0b59cc45240.png)
There’s something shady going on…
Immutable types¶
Cannot change their value
ints, floats, strings, tuples
Mutable types¶
Can change their value
All names that have the same value see the change! (Same value does not mean equal value!!)
Behavior when performing operations depends on the object’s implementation! E.g. in the earlier example
>>> list2 += [" world"]
is actually
>>> list2.__iadd__(["world"])
. So the behavior depends on the implementation of __iadd__. However
>>> list2 = list2 + [" world"]
is actually
>>> list2.__add__(["world"])
. So the behavior depends on the implementation of __add__.