gpt4 book ai didi

python - 函数结果与可变默认参数的连接

转载 作者:IT老高 更新时间:2023-10-28 22:00:31 25 4
gpt4 key购买 nike

假设一个函数具有可变的默认参数:

def f(l=[]):
l.append(len(l))
return l

如果我运行这个:

def f(l=[]):
l.append(len(l))
return l
print(f()+["-"]+f()+["-"]+f()) # -> [0, '-', 0, 1, '-', 0, 1, 2]

或者这个:

def f(l=[]):
l.append(len(l))
return l
print(f()+f()+f()) # -> [0, 1, 0, 1, 0, 1, 2]

而不是下面的,这会更合乎逻辑:

print(f()+f()+f()) # -> [0, 0, 1, 0, 1, 2]

为什么?

最佳答案

其实挺有意思的!

我们知道,列表 l在函数定义中仅在此函数的定义处初始化一次,并且对于此函数的所有调用,将有此列表的恰好一个副本。现在,该函数修改了这个列表,这意味着对该函数的多次调用将多次修改完全相同的对象。这是第一个重要的部分。

现在,考虑添加这些列表的表达式:

f()+f()+f()

根据运算符优先法则,这等价于:

(f() + f()) + f()

...和这个完全一样:

temp1 = f() + f() # (1)
temp2 = temp1 + f() # (2)

这是第二个重要的部分。

添加列表会生成一个 new 对象,而无需修改其任何参数。这是第三个重要部分。

现在让我们将我们所知道的结合在一起。

在上面的第 1 行中,第一次调用返回 [0] ,如你所料。第二次调用返回 [0, 1] ,如你所料。等一下!该函数将在修改后一遍又一遍地返回完全相同的对象(不是它的副本!)!这意味着第一个调用返回的对象现在已更改[0, 1]也!这就是为什么temp1 == [0, 1] + [0, 1] .

然而,加法的结果是一个全新的对象,所以[0, 1, 0, 1] + f()[0, 1, 0, 1] + [0, 1, 2] 相同.请注意,第二个列表也是您希望函数返回的内容。添加 f() + ["-"] 时会发生同样的情况:这会创建一个 list对象,以便对 f 的任何其他调用不会干扰它。

你可以通过连接两个函数调用的结果来重现这个:

>>> f() + f()
[0, 1, 0, 1]
>>> f() + f()
[0, 1, 2, 3, 0, 1, 2, 3]
>>> f() + f()
[0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5]

同样,您可以做到所有这些,因为您正在连接对同一个对象的引用。

关于python - 函数结果与可变默认参数的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57593294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com