0

I am new guy. Here is an example from python document.

def funtest(num, L=[]):
    L.append(num)
    return L
print(funtest(2))
print(funtest(3))
print(funtest(4))

I thought very function call should execute the same thing, which means L=[] in very function call. so I though the output should like this:

[2]
[3]
[4]

but the real answer is in below. It looks like the funtest() inherited the output from the last function call. And then continually pass it to next function call. I am confusing to it.

[2]
[2, 3]
[2, 3, 4]

When I change the code to below case:

def funtest(L=[]):
    L.append(L)
    return L
print(funtest([2]))
print(funtest([3]))
print(funtest([4]))

the real output go to this:

[2, [...]]
[3, [...]]
[4, [...]]

The output are quite different with the previous one. I am more confused now. Does anyone repair my mind shot? Thanks a lot

Jiang Liang
  • 326
  • 1
  • 2
  • 9
  • 3
    Does this answer your question? ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – Alan Hoover May 24 '20 at 00:31
  • @AlanHoover Yes. I did not search it before. – Jiang Liang May 24 '20 at 00:37

3 Answers3

1

The problem is that the default value of L is a mutable object (in your case an empty list).
In Python default values are evaluated at function definition time.
Every time you call the function, you get the same default value and if you add any content to the object (the list) you'll get all the previously added content.

The correct way to get a default list (or dictionary, or set) is to create it at run time inside the function.
This is a common mistake in Python with beginners devs.

You would like to read similar questions:

"Least Astonishment" and the Mutable Default Argument
Good uses for mutable function argument default values?

Yusef Maali
  • 2,201
  • 2
  • 23
  • 29
1

to explain what is happening ,

1st case

so the default values in python functions are instantiated only once , only while defining the function , so the list is only created while defining the function and you keep adding to it so now the result contains all the older values

this is true for all values which are mutable when used as default value for arguments in python

what can you do ?

in general use immutable values , and for the case of list you use None as the default value and in the function you check if list is None and create one empty list inside the function

read more here ( the first gotcha ) : https://docs.python-guide.org/writing/gotchas/

2nd case

now you are actually creating infinite list by appending same list to itself when you are doing L.append(L)

and whenever a list is too large to print , python shows those three dots in its place

read more here What does [...] (an ellipsis) in a list mean in Python?

ashish singh
  • 6,526
  • 2
  • 15
  • 35
0

move L to inside of function

def funtest(num):
    L=[]
    L.append(num)
    return L
print(funtest(2))
print(funtest(3))
print(funtest(4))

this re set the L

enter image description here

  • While moving L=[] inside the function solves your problem, accumulation can be a useful feature. You can reset it by calling the function with a blank list: print(funtest(5,[])) – LevB May 24 '20 at 06:17