Python – Empty list as a default argument in a python function
This is probably a python “feature” that every junior developer has bumped into – once you make an empty list as a default argument in Python, it works as expected only for the first object of the class. For the second object – not exactly. Don’t worry, everyone has hit that bug, even it they are not willing to admit it.

The bug actually looks like this:
class Task:
def __init__(self, title, description, urgency):
self.title = title
self.description = description
self.urgency = urgency
def complete_task(task, grouped_tasks = []):
task.status = "completed"
grouped_tasks.append(task.title)
return grouped_tasks
task1 = Task("Homework", "Physics and Math", 5)
work = complete_task(task1)
task2 = Task("Fun", "Civilization 5 ", 15)
fun = complete_task(task2)
task3 = Task("Sports", "Football", 3)
sports = complete_task(task3)
print("Homework", work)
print("Fun", fun)
print("Sports", sports)
And the result is this one:
Homework ['Homework', 'Fun', 'Sports'] Fun ['Homework', 'Fun', 'Sports'] Sports ['Homework', 'Fun', 'Sports']
However, the correct way to do it is with this function with the “grouped_tasks is None” check:
def complete_task(task, grouped_tasks = None):
task.status = "completed"
if grouped_tasks is None:
grouped_tasks = []
grouped_tasks.append(task.title)
return grouped_tasks
And the result looks like this:
Homework ['Homework'] Fun ['Fun'] Sports ['Sports']
The reason why? Well, I explained it in the YouTube video below, but just to underline it once more:
Python evaluates the function when it’s defined. The evaluation has a side effect: any mutable default arguments (lists, dictionaries, etc) are created during evaluation and become part of the function. In our example, a list object is created when the function is evaluated. Now that specific list object is used as the grouped_tasks argument whenever the function is called without a grouped_tasks argument being provided, as the code in the next listing shows.

Thanks and enjoy it!