1

Here is my example in Jupyter notebook. In one cell I have the following code:

def list_flatenning(source_list, running_list=[]):

    if [isinstance(x, list) for x in source_list]:
        # There are list elements in our list, continue with recursion
        for el in source_list:
            if isinstance(el, list):
                list_flatenning(el, running_list)
            else:
                running_list.append(el)
        return source_list, running_list
    else:
        return source_list, running_list

This is recursive function, which takes nested list and returns flat list. For example, this function transforms [1,[2,3]] into [1,2,3].

Now, if I call this function once from different cell:

list_flatenning([1,[2,3]])[1]

I will get back [1,2,3]. Executing the same cell again gives [1,2,3,1,2,3], and if I execute it one more time, then I will get [1,2,3,1,2,3,1,2,3] and so on and so forth.

So clearly running_list variable from the function gets remembers and grows on every call.

One way to fight it is to call function from the same cell where function is defined. Something like this will always produce consistent result:

def list_flatenning(source_list, running_list=[]):

    if [isinstance(x, list) for x in source_list]:
        # There are list elements in our list, continue with recursion
        for el in source_list:
            if isinstance(el, list):
                list_flatenning(el, running_list)
            else:
                running_list.append(el)
        return source_list, running_list
    else:
        return source_list, running_list


list_flatenning([1,[2,3]])[1]

I wonder if there is a better solution. Also if somebody could explain what exactly happening in Jupyter with recursive function, I would greatly appreciate?

P.S. Here is online Jupyter in case you want to try the code and do not have Jupyter installed.

user1700890
  • 7,144
  • 18
  • 87
  • 183
  • 1
    [Explanation of Python mutable default arguments](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – John Gordon Jun 30 '17 at 02:09

1 Answers1

2

It's got nothing to do with Jupyter, this is what Python does with kwargs. You should never use a mutable object as the default value for a kwarg.

Change it to:

def list_flatenning(source_list, running_list=None):
    if running_list is None:
        running_list = list()
Batman
  • 8,571
  • 7
  • 41
  • 80