Friday Challenge #2
Here is my second weekly challenge for the LinkedIn’s Python Developers Community. The original post is here.
Before you continue reading, see if you can work out the answer yourself.
The question is: what is the output?
a = [1, 2, 3]
b = [4, a]
del a
print(b)
The possible answers are:
A. [4, None]
B. [4]
C. Error
D. [4, [1, 2, 3]]
E. [4, ...]
F. Other
What do you think?
Let’s have a look at how Python stores information. Here is how I like to explain it.
When Python executes “a = 13234” it creates a new object. You can think of this as a box.
Python has different types of boxes for storing different things – boxes for whole numbers (integers), floating point numbers (floats), text (strings), multiple items (lists, tuples, dictionaries) and more.
13234 is a number, specifically an integer (a whole number). So Python creates an integer-box, and puts the number 13234 inside.
That is the “13234” part sorted. Next Python processes “a = …”.
Each box has a unique location or id. You can think of it as a house number in a very very long road or a phone number. The id() function returns the id of an object. For instance:
>>> a = 13234
>>> id(a)
140712608160400
Internally Python maintains a list of variable names. Each name points to an object.
Another way of putting this is that a name references an object. Or that an object is bound to a name.
This is similar to an old fashioned phone directory or address book.
Python adds the new name, “a”, and its reference, 13234, to its list of names.
Next we create another variable:
>>> b = 'Hello'
>>> id(b)
140712608719600
This creates a second box and a second entry in our ‘phone book’.
When you ‘copy’ a variable, this is what happens:
>>> c = b
>>> id(b)
140712608719600
>>> id(c)
140712608719600
‘b’ and ‘c’ now refer to the same object id, to the same box. There is only one box which contains the string ‘Hello’.
The ‘del’ statement removes a variable name from the list. It does not remove the object itself:
>>> del b
>>> id(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
Python keeps track of how many names each box has. This is called the ‘reference count’. When the reference count is zero, when a box has no names, the box is removed from memory.
>>> del c
Let’s get back to the challenge:
a = [1, 2, 3]
b = [4, a]
del a
print(b)
Line 1 creates 4 new objects: 3 integer ‘boxes’ with values 1, 2 and 3. Plus a list ‘box’ with references to the three integer objects. The list box doesn’t contain the numbers. Instead it points to the three boxes with the numbers.
Line 2 creates 2 new objects: An integer box with a value of 4. And a list box with a reference to the new integer object (the number 4) and a reference to the [1, 2, 3] list box.
Now both ‘a’ and b[1] refer to the [1, 2, 3] list.
b[0] refers to the 4 object.
Line 3 removes the name ‘a’.
Now only b[1] refers to the [1, 2, 3] list. b[0] still refers to the 4 object.
So b contains [1, 2, 3] followed by 4.
And finally, the answer is:
D. [4, [1, 2, 3]]
Well done if you got this yourself. And if not, hopefully you learned something new.
(And, for a training exercise, here is a link to a non-existing page)