def foo(a, l=[]):
l.append(a)
return l
print foo(10)
Result: [10]
print foo(20)
Result: [10, 20]
Why is this happening?
def foo(a, l=[]):
l.append(a)
return l
print foo(10)
Result: [10]
print foo(20)
Result: [10, 20]
Why is this happening?
This line:
def foo(a, l=[]):
is creating a list at definition time.
That same list is being used every time the function is called.
Normally something like def foo(a, l="some string"):
would work fine, but that's because string literals, integers and such are immutable and therefore it doesn't matter if every instance of the function accesses the same object in memory. Lists, on the other hand, are mutable.
You can get around this like so:
def foo(a, l=None):
if l is None:
l = []
l.append(a)
return l
This also creates a new list, but only upon execution of the function, in local scope. It won't reuse the same one.
When you give a default value to a function argument in python, it gets initialized only ONCE. That means even if you call your foo() a million times, you are appending to the SAME list.
print foo(10)
print foo(20, [])
output:- [20]
this time you are sending another list
reference so value will be inserted in another list
reference.
If you do
def foo(a, l=[]):
print id(l)
...
...
print foo(10)
print foo(20)
both time reference is same
140403877687808
[10]
140403877687808
[10, 20]
while in another case:-
def foo(a, l=[]):
print id(l)
...
...
print foo(10)
print foo(20, [])
reference changes:-
>>>
140182233489920
[10]
140182233492512
[20]
It's because
Default parameter values are always evaluated when, and only when,
the “def” statement they belong to is executed.
“def” is an executable statement in Python, and that default arguments are
evaluated in the “def” statement’s environment. If you execute “def” multiple times,
it’ll create a new function object (with freshly calculated default values) each time.
We’ll see examples of this below.
So here In your code, You are defining the list as default parameters. So it is evaluated only once when function is defined. Here come the reference of "def"
So only one object of list is created which is used multiple times whenever function is called and items get appended.
If you look the list identity then you will find function keeps returning the same object
>>> def foo(l=[]):
... l.append(1)
...return l
>>> id(foo())
12516768
>>> id(foo())
12516768
>>> id(foo())
12516768
The way to achieve what you want to do is
def foo(a, l=None):
if l is None:
l = []
#Do your stuff here with list l