The other day, one of my friends asked me for help in debugging some Python code that she wrote. All she had to do was implement a triangle()
function to make the following test pass.
def test_triangle():
expected = [
['a'],
['aw'],
['awe'],
['awes'],
['aweso'],
['awesom'],
['awesome'],
]
assert(triangle('awesome') == expected)
And this was her implementation of the triangle()
function
def triangle(input_string):
# constructing the base of the triangle
triangle_list = [[] * len(input_string)]
for index, element in enumerate(triangle_list):
# element is the ith list in triangle_list
element = [input_string[:index+1]]
return triangle_list
She was having trouble with passing the test and was visibly frustrated with her inability to perceive her mistake. The output of her triangle()
function was returning the following list, instead of what was expected
in the above test.
[
['awesome'],
['awesome'],
['awesome'],
['awesome'],
['awesome'],
['awesome'],
['awesome']
]
Even after coding for quite a while in Python now, I had to look twice, scratch my head once, before I arrived at the correct solution, with a chuckle. Can you spot the mistake in her code?
The culprit is in the line with the initial triangle_list
assignment
...
# constructing the base of the triangle
triangle_list = [[] * len(input_string)]
...
This sort of a mistake happens more often than not, when you don't pay much attention to how you are manipulating your lists. What is happening in the above line of code is the same copy of the empty list object was being populated len("awesome")
, i.e., 7 times, in triangle_list
. You can verify it by checking the id
of each object.
...
# constructing the base of the triangle
triangle_list = [[] * len(input_string)]
for index, element in enumerate(triangle_list):
# the following will print the same value for all elements in the loop
print(id(element))
...
Fortunately, as with everything else in Python, the fix was quite easy. Just had to make sure that a new "different" empty list was populated for every character in the string while # constructing the base of the triangle
. Like so:
...
# constructing the base of the triangle
triangle_list = [[] for _ in range(len(input_string))]
...
This is my first story; and I would appreciate an upvote, if you have liked reading it. Thanks. :)