我遇到了以下代码:
def f(x,l=[]):
for i in range(x):
l.append(i*i)
print(l)
f(2)
f(3,[3,2,1])
f(3)
返回:
[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]
我的问题是这个
为什么在第三个函数调用f(3)
中,我不被l=[]
中的def (f(x,l=[])
覆盖,然后返回[0,1,4]
?这是怎么回事?
当我这样做时,事情按预期进行。.
l=[]
[l.append(i*i) for i in range(2)]
print(l)
l=[1, 2, 3]
[l.append(i*i) for i in range(3)]
print(l)
l=[]
[l.append(i*i) for i in range(3)]
print(l)
打印:
[0, 1]
[1, 2, 3, 0, 1, 4]
[0, 1, 4]
我知道答案与python将数据存储在内存中的方式有关,但是即使用id(l)
探索(打印出与l相同的ID, f(2)
和f(3)
都使用,但是f(3, [3,2,1])
的ID不同。
谢谢您的见解!
答案 0 :(得分:0)
执行此操作的正确方法是在函数内部使用局部变量lst
,该变量负责您在函数内部进行的操作,而不是像这样对要传递的变量进行操作。
def f(x,lst=None):
lst = lst or []
for i in range(x):
lst.append(i*i)
print(lst)
f(2)
f(3,[3,2,1])
f(3)
哪个给您输出为
[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 4]
前一种方法不起作用的原因是,当在参数的默认值中检测到可变值(如列表或字典)时,它们在函数定义时仅被评估一次,这意味着修改的默认值。该参数将影响该函数的所有后续调用。
但是在更改的函数中,我正在制作一个新的局部变量以在列表上进行操作,该变量是传递的参数的副本,因此在这里我们不会遇到此问题。