我对python对默认函数参数的评估感到困惑。如文档(https://docs.python.org/3.6/tutorial/controlflow.html#more-on-defining-functions)
中所述def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
结果
[1]
[1,2]
[1,2,3]
但是
def f(a, L=[]):
L = L+[a]
return L
print(f(1))
print(f(2))
print(f(3))
结果
[1]
[2]
[3]
如果L仅被评估一次,那么该函数是否应该返回相同的结果?有人可以解释我在这里缺少什么吗?
这个问题与"Least Astonishment" and the Mutable Default Argument不同。这个问题质疑设计选择,而我在这里试图了解具体案例。
答案 0 :(得分:1)
你不是在追加,而是在这里创建一个新的L
:
>>> def f(a, L=[]):
L = L+[a] #Here you're making a new list with the default argument and a.
print(id(L))
return L
>>> f(1)
140489350175624
[1]
>>> f(1)
140489349715976
[1]
>>> f(2)
140489349718536
[2]
每次都可以看到id
L
更改。
但是当你使用append
时,它就像:
>>> def f(a, L=[]):
L.append(a) #Here you're just appending and NOT making a new list.
print(id(L))
return L
>>> f(1)
140489350175624
[1]
>>> f(12)
140489350175624
[1, 12]
>>> f(3)
140489350175624
[1, 12, 3]
>>>
阅读this。
答案 1 :(得分:1)
在
L.append(a)
在所有函数调用中,您将附加到相同的列表对象,因为列表是可变的。
而在:
L = L+[a]
您实际上重新绑定名称L
到L
和[a]
的串联。然后,名称L
成为函数的本地名称。因此,在重新绑定后,每个函数调用L
都会变得不同。