The most popular, some might say classic, interview task is the list task. This task assesses not only the candidate's ability to write code, but also their understanding of basic Python concepts, their ability to analyse results and find bugs, and their ability to document their code.
Task:
Implement add_to_list
function, that adds element item
to the list my_list
and returns this list.
# use provided code below to verify your implementation
def add_to_list(item, my_list=[]):
# enter your code here
return my_list
x = add_to_list(1)
print(x)
y = add_to_list(2)
print(y)
z = add_to_list(3, [4, 5])
print(z)
1. What values did you get for the variables x
, y
, and z
when you ran the code?
x = [1]
y = [1, 2]
z = [4, 5, 3]
2. What is the value of y
? Explain what is happening.
In Python, if a function defines a default argument as a modifiable object (in this case, an empty list), that object is only created once when the function is defined, not every time it is called, unless the list is explicitly passed.
The first run of add_to_list(1) created a list [1].
The secon run of add_to_list(2) uses the same list, rather than creating a new one, and so adds element 2 to it, giving [1, 2].
3. How does the add_to_list(3, [4, 5])
command behave differently than the previous two commands?
In the case of the run of add_to_list(3, [4, 5]), we explicitly passed the list [4, 5] as an argument to my_list, so the function used this new list instead of the default one.
Tasks:
1. Fix the add_to_list function so that it works correctly and the add_to_list(1) and add_to_list(2) commands create separate lists instead of using the same one.
2. Write a docstring for the fixed function.
3. Add a type annotation for the function's input and output parameters.
4. Explain why the modification works and what changes have been made.
docstring
)def add_to_list(item: int, my_list: list = None) -> list:
"""Adding an item to the list
Arguments:
:param item: the item to add to the list
:param my_list: the list to add the item to
Returns:
:param list: the list with the added item in it
"""
if my_list is None:
my_list = []
my_list.append(item)
return my_list
x = add_to_list(1)
print(x)
y = add_to_list(2)
print(y)
z = add_to_list(3, [4, 5])
print(z)
The function uses None as the default value for my_list and internally checks if my_list = None. If so, a new list is created.
The problem was that the object to be modified (the list) was created once when the function was defined, leading to undesirable behavior. It's worth noting that when we pass an existing list, we don't create a copy before pasting, we add directly to the existing list. It follows that if we want to have a new list — the solution needs to be refined.
Using None as the default and checking for None within the function ensures that each use without an explicit list will create a new empty list, and thus each use will have its own list.