can someone explain the concept of "strings (or whatever) being immutable"
Steven D'Aprano
steve at pearwood.info
Tue Jun 3 03:46:26 EDT 2014
On Mon, 02 Jun 2014 21:06:37 -0800, Deb Wyatt wrote:
> """a_string = "This is a string"
> a_string is pointing to the above string
>
> now I change the value of a_string
This is where English can lead us astray. "Change the value of a_string"
can mean two different things. An analogy may help make it clear.
Some people give their car a name. Suppose I call my car "Vera". I might
then "change the value of Vera" by replacing the engine with a more
powerful one, installing superchargers, giving the car a new paint job,
and replacing the tape desk with an MP3 player. The name "Vera" still
refers to the same physical car, but now it is quite different from how
it was before. This is equivalent to modifying a mutable value (like a
list) in-place.
On the other hand, I might instead trade in my car for a newer model, and
transfer the name with it. (I'm very unimaginative when it comes to names
-- if I had children, they would all be called Chris, and all my pets are
called Fluffy -- even the goldfish.) Whereas before Vera referred to a
blue Toyota, now it refers to a red Ford. This is equivalent to replacing
the string with a new string.
In Python terms, we call that "re-binding". "Binding" is another term for
assignment to a name. All of these things are binding operations:
import math
from random import random
x = 23
my_string = my_string.upper()
while these are mutation operations which change the value in-place:
my_list[0] = 42
my_list.append(None)
my_list.sort()
some_dict['key'] = 'hello world'
some_dict.clear()
Only mutable objects can be changed in place: e.g. lists, dicts, sets.
Immutable objects are fixed at creation, and cannot be changed: strings,
ints, floats, etc.
Some objects fall into a kind of grey area. Tuples are immutable, but
tuples can include mutable objects inside them, and they remain mutable
even inside the tuple.
t = (1, 2, []) # tuple is fixed
t[2] = [1] # fails, because you're trying to mutate the tuple
t[2].append(1) # succeeds, because you're mutating the list inside t
> a_string = "This string is different" I understand that now a_string is
> pointing to a different string than it was before, in a different
> location.
>
> my question is what happens to the original string?? Is it still in
> memory somewhere, nameless? """
> That was just the first question. What does immutable really mean if
> you can add items to a list? and concatenate strings? I don't
> understand enough to even ask a comprehensible question, I guess.
No, it's an excellent question!
When an object is *unbound*, does it float free in memory? In principle,
it could, at least for a little while. In practice, Python will recognise
that the string is not being used for anything, and reclaim the memory
for it. That's called "garbage collection". There are no promises made
about when that happens though. It could be instantly, or it could be in
an hour. It depends on the specific version and implementation of Python.
(CPython, the standard version, will almost always garbage collect
objects nearly instantly. Jython, which is Python on the Java Virtual
Machine, only garbage collects objects every few seconds. So it does
vary.)
In the case of lists, we've seen that a list is mutable, so you can
append items to lists. In the case of string concatenation, strings are
immutable, so code like this:
s = "Hello"
s += " World!"
does not append to the existing string, but creates a new string, "Hello
World!", and binds it to the name s. Then the two older strings, "Hello"
and " World!" are free to be garbage collected.
--
Steven
More information about the Python-list
mailing list