Respected members, why does my Python function remember the old list?
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…
Accepted answer
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.