0

I am following the Python tutorial.

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

When I call f

print(f(1))
print(f(2))
print(f(3, L=[]))
print(f(4))

I get

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

Why it returns [1, 2, 4] after [3] instead of [3, 4]?

Gui
  • 53
  • 5

4 Answers4

1

The problem is that you declare L=[] in the arguments. This creates the List that is assigned to L only once. For the third case where you have

print(f(3, L=[]))

you pass an empty list to the function for the parameter L. This does not overwrite L but is only valid for that specific function call. For the next call, it takes the default argument list again, which contains at that point in time [1,2].

It is (as far as I know) not possible to reassign the default parameter after initialization.

This question may also be of interest to you as it talks about mutable default arguments

Syrius
  • 941
  • 6
  • 22
1

If you want to get the same result you need to initialize a list and pass it to the function.

def f(a, L):
    L.append(a)
    return L
        
L = []
print(f(1, L))
print(f(2, L))
L = []
print(f(3, L))
print(f(4, L))

The output is

[1]                                                                                                                                                                                
[1, 2]                                                                                                                                                                             
[3]                                                                                                                                                                                
[3, 4] 
TOZX
  • 181
  • 1
  • 8
0

You're getting a different value because of L=[] default value and it is mutable. The tutorial link you provided there clearly stated that

  • Default value is evaluated only once
  • the default is a mutable object such as a list, dictionary, or instances of most classes

So, When you pass another L=[] in your f() function then L=[] is initiating for a new one and return a single result. But after calling f(4) it's getting to default function and return update result

   def f(a, L=[]):
        L.append(a)
        return L
    
    print(f(1))
    print(f(2))
    print(f(3, L=[]))
    print(f(4))
mhhabib
  • 2,975
  • 1
  • 15
  • 29
  • Thanks, but I still do not understand why it returns [3] and then [1, 2, 4]. Could you be more didactic please? – Gui Dec 11 '20 at 11:45
  • @Gui well assume you have to make `sum` the value of `a` if it is `5` else print the value that is not 5. Now compare with `f(a, L=[])` where `L=[]` default. If the condition meets then it will append to `L=[]` list or print the value that comes from the user end. – mhhabib Dec 11 '20 at 16:14
0

Looks like that you are creating a new list object in memory by resetting a new value object of L at the third time it runs, so it stores the the a variable value in the new list object instead of appending to the old one that has been in memory already, but in step four and since L=[] has hasn't been changed this time it still points to the same old list object in memory, so step 4 a variable value gets stored there as well as step one and two.

here is a simple example: if we modified the code a little bit to debug what's happening here, you will see that the L variable get's assigned to a new list object in memory at step 3.

def f(a, L=[]):
    L.append(a)
    print(f'Your function list id: {id(L)}, now gets assigned a value of: {a}')
    return L


print(f(1))
print(f(2))
print(f(3, L=[]))
print(f(4))
Muhammad Hawash
  • 126
  • 1
  • 1
  • 10