Post

@PythonPr Answer: B) hello
Solution: On the surface it looks trivial.
s is initialized 'hello'.
t is assigned s.
s is modified to upper. So it 'HELLO' now
t is printed. What is the value of t?
t hasn't explicitly been changed, so it's going to the initial 'hello'.
But you might
+
English

@PythonPr have seen some bizarre stuff with lists.
Where you change one variable, and the change automatically reflects in another variable. Eg.
a = []
b = a
b.append(1)
the append to b automatically modifies `a` as well.
Why doesn't that happen here?
The reason is because
+
English

@PythonPr strings are immutable, ie,
after creation, they cannot be modified. (unlike lists)
therefore when
s = 'hello'
is initialized, the object 'hello' is created in memory.
As this is a string, no way it's going to be changed.
t = s
t references the same object as s.
+
English

@PythonPr s.upper()
s.upper cannot modify the existing object 'hello' because it's immutable.
So, s.upper() has NO CHOICE other than create a new string object 'HELLO' and return it.
The returned object is referenced to s via `=`
s = s.upper()
So this was a re-assignment, ie,
+
English

@PythonPr s now references a different object than before.
This wasn't a mutation where s references the same object, but the object itself has changed.
So, what about t?
t still references the original object, which hasn't changed at all.
Therefore, the value of t is 'hello'.
English

