Skip to content
question

Respected members, why does my Python function remember the old list?

Lakshmi Prasad@lakshmi_teaches_py

October 11, 2026 · 1 min read

Respected members,

I am a mathematics teacher learning Python so that I can teach my Class 9 students properly. I wrote a small function to collect marks, and something very strange is happening. Kindly see:

def add_mark(mark, marks=[]):
    marks.append(mark)
    return marks

print(add_mark(45))   # [45]
print(add_mark(78))   # [45, 78]   I expected [78]
print(add_mark(62))   # [45, 78, 62]

Each time I call the function without the second argument, I expected a fresh empty list. But it keeps the old values. My students noticed it before I did, which was a little embarrassing for the teacher.

Is this a bug in Python? We are using Python 3.12 on the school lab computers. Kindly also guide me how to explain it to fourteen year old children, because "it is like that only" will not satisfy them.

Thanking you,
Lakshmi

Accepted answer

Graham Whitfield#3 in Read The Docs12 likes

Lakshmi, Anitha is right, and you are in good company: this has caught professional programmers for thirty years. Python evaluates a default value once, when the def line runs, not each time the function is called. So there is exactly one list, created when the function was defined, and every call that does not pass marks gets that same list and appends to it. You can show the children the shared list directly. After your three calls: print(add_mark.__defaults__) # ([45, 78, 62],) The usual fix is to use None as the default and make a fresh list inside: def add_mark(mark, marks=None): if marks is None: marks = [] marks.append(mark) return marks For fourteen year olds, try this: the default list is one notebook kept on the teacher's desk. Every student who does not bring their own notebook writes in the desk notebook. By the third student, the page is already full of other people's marks. The fix gives each student a new notebook when they arrive. It is also in the official Python tutorial, in the section on default argument values, with a warning in a box saying the default is evaluated only once. Showing them that box is a nice lesson in itself: the docs knew before we did. Cheers, G.

View in the thread

Get the best of #read-the-docs weekly

One email each Monday with the most useful posts. No spam; unsubscribe in one click.

Comments

8

Sign in to join the conversation.

Sign in to comment
Anitha Joseph@anitha_miss#4 in Read The Docs
Lakshmi, this is not a bug, it is one of the most famous surprises in Python. Your students are sharp! Small hint while someone writes the full answer: the default value is made only once.
0 net votes

Accepted answer

Graham Whitfield@greybeard_graham#3 in Read The Docs
Lakshmi, Anitha is right, and you are in good company: this has caught professional programmers for thirty years. Python evaluates a default value once, when the def line runs, not each time the function is called. So there is exactly one list, created when the function was defined, and every call that does not pass marks gets that same list and appends to it. You can show the children the shared list directly. After your three calls: print(add_mark.__defaults__) # ([45, 78, 62],) The usual fix is to use None as the default and make a fresh list inside: def add_mark(mark, marks=None): if marks is None: marks = [] marks.append(mark) return marks For fourteen year olds, try this: the default list is one notebook kept on the teacher's desk. Every student who does not bring their own notebook writes in the desk notebook. By the third student, the page is already full of other people's marks. The fix gives each student a new notebook when they arrive. It is also in the official Python tutorial, in the section on default argument values, with a warning in a box saying the default is evaluated only once. Showing them that box is a nice lesson in itself: the docs knew before we did. Cheers, G.
12 net votes
Lakshmi Prasad@lakshmi_teaches_py#2 in Read The Docs
Respected Graham sir, thank you very much. The __defaults__ trick is wonderful, I will show it on the projector tomorrow. The desk notebook explanation the children will understand immediately. Thanking you.
0 net votes
Graham Whitfield@greybeard_graham#3 in Read The Docs
Lakshmi, please drop the 'sir'. You have taught for 25 years and I am a retired man who grows tomatoes. Cheers, G.
1 net votes
Rhys Llewellyn@rhys_teaches_code#4 in Read The Docs
This catches my Year 12s every year too. The tutorial really does have that warning box, so it's a lovely moment to show children that reading the docs is a real skill. Diolch for posting, Lakshmi.
1 net votes
Ryan Goh@ai_maxi_ryan#4 in Read The Docs
or just ask chatgpt next time, it explains this in 2 seconds 🤖
2 net votes
Graham Whitfield@greybeard_graham#3 in Read The Docs
Ryan, she asked people, got an answer, a reference to the docs and a classroom demonstration, and is teaching thirty children with it tomorrow. Your 2 seconds would not have included the children. Cheers, G.
1 net votes
Lakshmi Prasad@lakshmi_teaches_py#2 in Read The Docs
Thank you for the suggestion. I did try that first, but I wanted to understand it well enough to explain it, and the people here are very kind. 🙏
0 net votes