1

I read the following tutorial:

https://docs.python.org/3/tutorial/controlflow.html#default-argument-values

and do some experiments.

I found that default argument is very confusing. Could anyone can explain the following phenomenon?

First, I tried following code:

Code 1

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

The results are:

[1]
[1, 2]
[1, 3, 3]

According to the document, this is because that default argument L is mutable and its value will be evaluated only once when the function is defined. That looks good!

However, I tried Code 2 next:

Code 2

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

and the results are:

[1]
[2]
[3]

To study the default argument, I improved Code 2 and tried Code 3:

Code 3

def f(a, L=None):
    print(type(L))
    print(id(L))
    print(L)

    if L is None:
        L = []
        print(id(L))

    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

the results are:

<class 'NoneType'>
4381397320
None
4385607368
[1]

<class 'NoneType'>
4381397320
None
4385607496
[2]

<class 'NoneType'>
4381397320
None
4386251464
[3]

This shows that the L that before the if statement is always None and has different id with the id of L that in the if statement, and the former's id is fixed while the latter changes in every run.

I also tried the following code:

L_r = f(5)
print(id(L_r))

and the result is:

<class 'NoneType'>
4381397320
None
4385607496
4385607496

This shows that L_r has the same id as the L in the if statement.

Can you explain what the difference between L outside the if statement and in the if statement and why?

Thank you!

zchenkui
  • 139
  • 1
  • 10

1 Answers1

1

if you don't give L, default arguments will create a variable L, and reuse it for your mutiple calls, so in Code 1, it is edited in the same L.

but in Code 2, you change L in function:

if L is None:
   L = []

default parameter L=None is always same(id=4381397320) as Code 1, but this statement make L refernce to a new variable, so the id will be different, and result will not be accumulated.

Hope that helps you, and comment if you have further questions. : )

recnac
  • 3,744
  • 6
  • 24
  • 46