The intended objective of function foo
is to add the number provided as argument to the list and, in case it is 0, reset the list. First I wrote this program:
def foo(n, bar = []):
if n == 0:
bar = []
print("list empty")
else:
bar.append(n)
for y in bar:
print(y, end=', ')
print()
foo(5)
foo(3)
foo(0)
foo(6)
output:
5,
5, 3,
list empty
5, 3, 6,
but it looks like bar = []
is ignored. Then I changed bar = []
with bar.clear()
and it works as I thought:
def foo(n, bar = []):
if n == 0:
bar.clear()
print("list empty")
else:
bar.append(n)
for y in bar:
print(y, end=', ')
print()
foo(5)
foo(3)
foo(0)
foo(6)
output:
5,
5, 3,
list empty
6,
I haven't understood why bar.clear()
works differntly from bar = []
since clear()
should
Remove all elements from the set.
so the same thing bar = []
does.
Edit: I don't think my question is a duplicate of “Least Astonishment” and the Mutable Default Argument, I'm aware that
The default value is evaluated only once.
(from the official tutorial) but what I am asking is, why bar = []
doesn't edit (in this case clear) the list, while append and clear does?
bar = []
rebinds bar
; it creates a brand new empty list
, and binds the name bar
to it. It doesn't matter what bar
was before; it could have been an int
, a tuple
, or dict
, and it's irrelevant now, because it's now bound to a brand new list
. The old binding no longer exists in the current method call, but the original list
remains in existence as the value of the default argument to foo
(note: Mutable defaults are considered surprising and ugly because of this confusion).
bar.clear()
calls a method on the existing list
, which tells that list
to clear itself (and has no effect on what bar
refers to; it better be something with a clear
method, but other than that, it's not really required that it be a list
). Since it's the same bar
you started with (referencing the same mutable default value cached in the function defaults), that affects your future calls (because bar
continues to refer to the list
you provided as the mutable default).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With