1

I am experimenting with calling a function with different arguments. Now I know from the Python Docs (Python Tutorial 4.7.1. Defining Functions) - that a function accumulates the arguments passed to it on subsequent calls. Because of this after the first call I was expecting the id() of the list object in my function to remain constant, but it does not. Why are the id()'s different?

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

>>> f(1)

2053668960840
[1]

>>> f(1)

2053668960840
[1, 1]

>>> f(1,[9])

2053668961032
[9, 1]

>>> f(1,[9])

2053669026888
[9, 1]

>>> f(1,[9])

2053668961032
[9, 1]

>>> f(1,[9])

2053669026888
[9, 1]
MarkH
  • 31
  • 5
  • Please include a reference to that Python doc. – Prune Mar 22 '18 at 21:33
  • 1
    when you pass an argument for `L`to the function, the printed id will be the id of the passed argument (and passing the same *value* again is not equivalent to passing the same *object*). Only when you omit the argument it will use the interal default object, which will keep its id. – Zinki Mar 22 '18 at 21:34
  • Why would the ids be the same? You’re passing a new list each time. – internet_user Mar 22 '18 at 21:35
  • Possible duplicate of ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – Scott Mermelstein Mar 22 '18 at 21:36
  • @ScottMermelstein not a duplicate, but a good read to avoid using those mutable defaults though. Well, it's close actually... but more subtle – Jean-François Fabre Mar 22 '18 at 21:41

1 Answers1

4

The default argument is bound to the function upon creation, it is always the same object in memory. That's why you are seeing the same id whenever you call your function without providing the second argument.

When you call your function with the second argument, in your case freshly created lists, the assignment L=<list called with> implicitly takes place inside the function body before any other code is executed. You see the id of your freshly created lists in this case.

timgeb
  • 76,762
  • 20
  • 123
  • 145
  • 1
    So by passing a list as my second argument, the default argument object still exists (as part of that function) but is not used because I have provided an alternative object to operate on? – MarkH Mar 22 '18 at 22:16
  • @MarkH exactly! – timgeb Mar 22 '18 at 22:36