PEP572 中的海象运算符示例

Chr*_*isW 2 python pep python-3.8

PEP572中给出的示例之一是

# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]
Run Code Online (Sandbox Code Playgroud)

目前在 python 中,您必须执行以下操作之一:

# option 1
y = f(x)
[y, y**2, y**3]
Run Code Online (Sandbox Code Playgroud)

或者

# option 2 
[f(x), f(x)**2, f(x)**3]
Run Code Online (Sandbox Code Playgroud)

该示例暗示此处的选项 2 可以改进,但我从未见过比第一个选项更推荐的选项。选项 2(以及海象运营商)比选项 1 更好的原因有哪些?

nor*_*ok2 7

只是为了让事情清楚:

[y := f(x), y**2, y**3]
Run Code Online (Sandbox Code Playgroud)

相当于:

y = f(x)
[y, y**2, y**3]
Run Code Online (Sandbox Code Playgroud)

f(x)只被调用一次)

但是,一般来说,不是这个:

[f(x), f(x)**2, f(x)**3]
Run Code Online (Sandbox Code Playgroud)

f(x)被称为三遍)

因为潜在f() 的副作用(或潜在的不必要的计算负担,如果f()函数)。

因此,在一般情况下,更换[f(x), f(x)**2, f(x)**3][y := f(x), y**2, y**3]应仔细检查。


例如:

def f(x):
    print('Brooks was here.')
    return 2 * x


x = 1
y = f(x)
l1 = [y, y**2, y**3]
Run Code Online (Sandbox Code Playgroud)

打印Brooks was here.一次,同时:

l2 = [f(x), f(x)**2, f(x)**3]
Run Code Online (Sandbox Code Playgroud)

将打印Brooks was here.三遍。当然,l1 == l2


因此,要更直接地回答您的问题,您可能需要使用:

[f(x), f(x)**2, f(x)**3]
Run Code Online (Sandbox Code Playgroud)

而不是这个

y = f(x)
[y, y**2, y**3]
Run Code Online (Sandbox Code Playgroud)

当您对副作用特别感兴趣时,无论可能是什么。

  • +如果后续的“f(x)”给出相同的结果并且没有副作用,第二个选项允许我们使用列表推导式而不是循环。但是,如果“f(x)”需要很长/大量的内存来计算,我们必须使用第一个选项的循环...或者使用新的海象运算符保留列表理解,所以我们将计算“f(x)” ` 只一次。 (2认同)