"Into the pit" and "out of the pit" when the list (list) is used as a parameter in the python function

In a Python function, if one of the passed parameters is a list , then you should pay attention, there are pits here.

into the pit

dig a hole

def f(x,li=[]):
    for i in range(x):
        l.append(i*i)
    print(l)
 
print('---1---')
f(4)
print('---2---')
f(5)

expected results

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]

Results of the

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 0, 1, 4, 9, 16]

out of the pit

When the function is defined, the value of the default parameter list  in the function is saved  , that is, the list li=[];

If a new list is passed in each call, the passed list is used, if not passed, the default parameter (li=[]) saved when the function is defined is used;

In the above two calls, no new list is passed (the default list li=[] is used), the program will call the default parameters saved when the function was defined ((li=[]));

When the list is appended, it will append the value based on the original li=[], so the above result will be produced.

Identification by the ID of the printed list

Print the ID of the list li=[]:

def f(x,l= []):
     print (id(l)) # add print id
     for i in range(x):
        l.append(i*i)
    print(l)
 
 
print('---1---')
f(4)
print('---2---')
f(5)

result:

---1---
140306123906248
[0, 1, 4, 9]
---2---
140306123906248
[0, 1, 4, 9, 0, 1, 4, 9, 16]

will find that the ID values ​​are the same;

It means that the default parameter li=[ ] when the function is defined is used in the two executions

Pass a new list into it when executing

Print the ID of the list li=[] and the ID of the new list passed:

def f(x,l=[]):
    print(id(l))
    for i in range(x):
        l.append(i*i)
    print(l)
 
 
print('---1---')
f(4)
print('---2---')
f(5,[])
print('---3---')
f(6)

result:

---1---
140017293614280
[0, 1, 4, 9]
---2---
140017293614472
[0, 1, 4, 9, 16]
---3---
140017293614280
[0, 1, 4, 9, 0, 1, 4, 9, 16, 25]

You will find that the ID printed when executing the function that passes an empty (new) list is different, and the one that is not passed is the same;

When an empty list is passed, the passed empty list will be used in the function body. When not passed, the function default value li=[ ] will be used, so the above result will be produced.

optimization

If you want to achieve the expected result, you only need to judge in the function body:

def f(x, li= []):
     if  not li:
         #If li is not empty, go down (empty the list); if it is empty, do not go 
        li = []
     for i in range(x):
        li.append(i * i)
    print(li)


print('---1---')
f(4)
print('---2---')
f(5)
print('---3---')
f(6)

result:

---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]
---3---
[0, 1, 4, 9, 16, 25]

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325355812&siteId=291194637
Recommended