[Python] The special case of using a list as a default parameter in a function parameter

If we define a function, if there is a default parameter list in the parameter, we will encounter some problems when the function is called

Let's look at the following code

def fn(num,lst=[]):
    for i in range(num):
        lst.append(i*i)
    print(lst)

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

You might expect the output to be something like this

[0, 1]

[0]

[3, 2, 1, 0, 1, 4]

[0, 1, 4] 

But in fact, the output of the program is like this

[0, 1]
[0, 1, 0]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 0, 1, 4]

Why does the above situation occur?

The function of the function fn is to append the result of the square of the integer from 0 to (num - 1) to the list lst, and print out the value of the list lst

When the function fn is executed for the first time, the default value [] of the parameter lst is created, this default value will only be created once, fn(2) adds 0 and 1 to the list lst, and prints out the value of lst [ 0 ,1]

When the function fn is executed for the second time, the default parameter lst is [0,1] instead of [], because the parameter lst is only created once, so fn(1) adds 0 to the list lst, and prints out the value of lst [0,1,0]

When the function fn is executed for the third time, since we specified lst=[3,2,1] when calling fn(3,[3,2,1]), so fn(3,[3,2,1] ]) adds 0, 1 and 4 to the list lst, prints the value of lst as [3,2,1,0,1,4]

When the function fn is executed for the fourth time, the default parameter lst is used, so the value of the default parameter lst is [0,1,0], so fn(3) adds 0, 1 and 4 to the list lst, and prints out The value of lst is [0,1,0,0,1,4]

In order to facilitate our further understanding, we can output the id of lst in the fn function

def fn(num,lst=[]):
    print(id(lst))
    
    for i in range(num):
        lst.append(i*i)
    
    print(lst)

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

The output is as follows

1965815826440
[0, 1]
1965815826440
[0, 1, 0]
1965816443208
[3, 2, 1, 0, 1, 4]
1965815826440
[0, 1, 0, 0, 1, 4] 

From the above results, we can find that when calling fn(2), fn(1) and fn(3), the id of the default parameter lst has not changed, while the parameter lst of calling fn(3,[3,2,1]) The id has changed

So how can we avoid the pitfalls mentioned above?

If you want to use the default list to be [] every time the function is called, you can make the following modifications

method 1

def fn(num,lst=None):
    if lst is None:
        lst = []
    
    for i in range(num):
        lst.append(i*i)
    
    print(lst)

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

Method 2

def fn(num,lst=[]):
    for i in range(num):
        lst.append(i*i)
    
    print(lst)
    lst.clear()

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

The output is as follows

[0, 1]
[0]
[3, 2, 1, 0, 1, 4]
[0, 1, 4] 

Guess you like

Origin blog.csdn.net/Hudas/article/details/130392819