Mutation in strings and lists
Say we have a string and want to change it to upper case. We’ve learned that we can use the str.upper()
function to acheive this:
But what do we do if we only want to change the first 4 letters to uppercase? For “XENA, Warrior Princess”?
We might be tempted to write code like in the following cell:
The TypeError
that we get from this is because strings are immutable.
immutable: unchangeable
What’s happenning in the background when we have the following code is that we’re actually creating new strings.
This is why we need to use the accumulator pattern when we’re creating new strings — we’re rebuilding new strings from old ones.
Lists & mutability
Lists are mutable.
mutable: changeable
This means that we can update the contents of a list.
For example, let’s take a look at the following code.
Notice that this is a way that strings and lists are different from each other!
List mutating functions (adding and deleting elements)
Take a look at the following functions: list.append(element)
and del list[index]
. These are how we add and delete values to/from lists. They are mutator functions – they change the value of the list instead of returning a new version of the list to us.
Mutator functions vs. pure functions
We say that a mutator function is any function that changes the contents of the list passed to it.
We say that a pure function is any function that returns a new list rather than changing the contents of the list passed to it.
# TODO: compare and contrast the behavior of the following two functions
# Call these functions and see how they are different from one another!
def list_add_one_mutate(my_list):
for i in range(len(my_list)):
my_list[i] += 1
def list_add_one_pure(my_list):
added = []
for i in range(len(my_list)):
added.append(my_list[i] + 1)
return added
You might have guessed that this mutation behavior of lists can make the question of scope quite complicated–that’s a correct intuition.
Lists as parameters and Scope
There will be a whole section of course notes exploring how complicated this is but for the time being here’s a summary: when lists are passed as parameters, their value is not passed (like str
, int
, float
, and bool
), rather, the actual list that you are working with is passed to the function. No copies are made.
It’s like lending your friend your notebook (lists) instead of making a copy of one of the pages (as with str
, int
, float
, and bool
).