If two variables refer to the same list, any change to the list will be reflected by both variables:
>>> x = numbers
>>> x.clear()
>>> numbers
[]
Strings are immutable in #Python. That means that there is no way to "change" a string object in Python.
Try as hard as you might, you cannot change strings. You can only make NEW strings.
name = "Trey"
name = name + "!" # makes a new string
name += "!" # same as above
If you play around with the built-in id function, you'll see that anything you do to a string that SEEMS like it may change the string actually returns a new string instead.
>>> name = "Trey"
>>> id(name)
139687084218480
>>> name = name.lower()
>>> id(name)
139687076401968
So mutable objects can change and immutable objects can't. Simple, right?
Not so fast... tuples are where things start to get fuzzy.
At first glance, tuples seem just as immutable as strings. But unlike strings, a tuple's value can change (depending on how you define "value").
If 2 names point to the same tuple and we "change" one, we're (again) just making a new tuple:
>>> a = b = (3, 4)
>>> id(a)
139687093427712
>>> a += (5, 6)
>>> id(b) # b is the old tuple
139687093427712
>>> id(a) # a is a new one
139687084242496
>>> a
(3, 4, 5, 6)
>>> b
(3, 4)
But what if our tuple contains a mutable object?
>>> result = (True, {"name": "Trey"})
>>> again = result
>>> result[1]["name"] = "Jay"
>>> again
(True, {'name': 'Jay'})
When we changed the dictionary our tuple contains, the original tuple seemed to change too! 😦
This is possible because tuples don't "contain" objects. They just contain references (a.k.a. "pointers" or "bindings") to objects.
Our tuple still points to the same dictionary. But the dictionary it's pointing to happened to have changed.
It's a bit fuzzier though because a tuple which points to a mutable object can have its sense of equality change:
>>> result = (True, {"name": "Trey"})
>>> other = (True, {"name": "Trey"})
>>> result == other
True
>>> result[1]["name"] = "Jay"
>>> result == other
False
In general, if an immutable object can contain a reference to a mutable object (as tuples can), then it's possible to make an "immutable" object which can *seem* to "change" (by changing one of the objects it contains a reference to).
Let's talk about what these methods do and why I recommend these ones first. 🧵
1️⃣ The string join method accepts an iterable of strings to join together.
It should be called on the separator you'd like to join by (e.g. " ", "\n", ",", ""). This is a string method: it's " ".join(my_list) and not my_list.join(" ").
While teaching comprehensions I sometimes see students do this:
numbers = [2, 1, 3, 4, 7, 11]
squares = []
[squares.append(n**2) for n in numbers]
Comprehensions are for building up a new list, but that one above actually builds up *two* new lists. 🧵
From a Python prompt, you can see what's going on:
>>> [squares.append(n**2) for n in numbers]
[None, None, None, None, None, None]
Comprehensions return a new list and the items in that list come from that first expression in the comprehension. squares.append returns None. 😦
We *do* modify the squares list:
>>> squares
[4, 1, 9, 16, 49, 121]
But that's a side effect, which comprehensions aren't supposed to have. Here's another comprehension with a side effect:
>>> [print(n**2) for n in numbers]
4
1
9
16
49
121
[None, None, None, None, None, None]
In Python, variables and data structures don't "contain" objects.
This idea is easy to miss when new to Python and it can be hard to internalize.
Let's talk about this. 🧵
Note: "value" and "object" are synonyms in this thread and so are "variable" and "name".
Variables in Python aren't "buckets containing things" but "pointers" (they point to values). The word pointer may sound scary (it is scary in C), but it mostly means what it sounds like.
An arrow connects each variable to a value and 2 variables can point to the same value. ➡
Assignment statements point a variable to a value. That's it. Python doesn't copy anything when you assign.
So this is an odd thing to do:
>>> x = y
Because we've pointed two names to the same value. So what? Why does that matter? 🤔