Default argument in recursive functions

b
benjamin (2490 points)
0 6 21
asked Jan 14, 2021 in Programming in Python by benjamin (2,490 points)
edited Jan 14, 2021 by benjamin
Hello.

While doing some exercise to prepare for the exam I found myself multiple times with the same "bug" ( allow me the term). Whenever I define a recursive function with some default parameters if I do not specify in the function call those default arguments everything goes wild ( wrong output for some of the tests) .

For example I define the recursive function foo like:

def foo(path,dic ={}, level =1) :

And I call it with :

foo(path)

It doesn't work, while if I call in the following way :

foo(path, {}, 1)

It works fine.

I am really curious to understand why this happens.

Thank for any answer in advance!!!!

PS when I talk about the call I mean not in the recursive function itself but when I call it from the "main"
373 views

1 Answer

S
Silktrader (2550 points)
1 6 16
answered Jan 14, 2021 by Silktrader (2,550 points)

This (somewhat unexpected) behaviour is peculiar to Python and can be put to good use.

Default arguments are evaluated once when functions are first instantiated; future function calls won't trigger new instances of default arguments.

In your case, the same dictionary will be reused every time you omit the "dic" argument and rely on the default one. Even though the default "dic" dictionary will be empty at the start of the first call, its elements could change during execution and the next function call would operate on the "mutated" default not empty dictionary.

This possible issue doesn't come up when one uses immutable default arguments. Sometimes, to avoid issues with mutable default arguments, I use this pattern:

def foo(path, dic=None, level=1) :
  dic = dic or {}

... which is similar to the safer (no coercion):

if dic is None:
  dic = {}