First I'm going to start like everyone else. I'm new to python. My teacher gave me the problem:
def f(a, b, c):
a = 1
c = b
c[0] = 2
a = 10
b = [11, 12, 13]
c = [13, 14, 15]
f(a, b, c)
print a, b, c
It prints:
10 [2, 12, 13] [13, 14, 15]
I understand that a stays at 10 because integers are immutable, but I don't understand why b changes and c doesn't.
Mutable is a fancy way of saying that the internal state of the object is changed/mutated. So, the simplest definition is: An object whose internal state can be changed is mutable. On the other hand, immutable doesn't allow any change in the object once it has been created.
If a mutable object is called by reference in a function, the original variable may be changed. If you want to avoid changing the original variable, you need to copy it to another variable. When immutable objects are called by reference in a function, its value cannot be changed.
There is an important difference in passing values to a function depending on whether the value is from a mutable or immutable data type. All values of primitive data types like numbers and boolean values in Python are immutable, meaning you cannot change any part of them.
A first fundamental distinction that Python makes on data is about whether or not the value of an object changes. If the value can change, the object is called mutable, while if the value cannot change, the object is called immutable.
c = b
c[0] = 2
Since you're setting c
to point to b
, You could just as easily do this:
def f(a, b, unused): # notice c isn't in the parameter list
a = 1
c = b # c is declared here
c[0] = 2 # c points to b, so c[0] is b[0]
Now it's obvious that c
is always the same as b
, so why not just remove it:
def f(a, b, unused):
a = 1
b[0] = 2
And now it's clear that you're changing the first element of b
and not doing anything to c
, and remember, this is functionally identical to the original.
The key is to understand the variables as pointers under the hood:
def f(a, b, c):
a = 1 # a is a single scalar value, so no pointing involved
c = b # point the local "c" pointer to point to "b"
c[0] = 2 # change the 2nd value in the list pointed to by "c" to 2
When you call f(a,b,c), only b actually gets changed. The "c" variable inside the function implementation is different from the "c" implementation outside the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With