问题
One of the examples given in PEP572 is
# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]
currently in python, you'd have to do one of the following:
# option 1
y = f(x)
[y, y**2, y**3]
or
# option 2
[f(x), f(x)**2, f(x)**3]
the example implies that option 2 here could be improved, but I have never seen that recommended over the first option. Is there ever a reason why option 2 (and therefore the walrus operator) would be better than option 1?
回答1:
Just to make things clear:
[y := f(x), y**2, y**3]
is equivalent to:
y = f(x)
[y, y**2, y**3]
(f(x)
is called only once)
but, in general, not this:
[f(x), f(x)**2, f(x)**3]
(f(x)
is called three times)
because of potential f()
side-effects (or potential unnecessary computational burden, if f()
is a pure function).
So, in general, replacing [f(x), f(x)**2, f(x)**3]
with [y := f(x), y**2, y**3]
should be inspected carefully.
For example:
def f(x):
print('Brooks was here.')
return 2 * x
x = 1
y = f(x)
l1 = [y, y**2, y**3]
prints Brooks was here.
once, while:
l2 = [f(x), f(x)**2, f(x)**3]
will print Brooks was here.
three times.
Of course, l1 == l2
.
So, to answer your question more directly, you may want to use:
[f(x), f(x)**2, f(x)**3]
and not this
y = f(x)
[y, y**2, y**3]
when you are specifically interested in the side-effects, whatever that might be.
回答2:
A walrus with dynamic programming, it could be faster depend on f(x)
.
e = 1
[e := e * f(x) for i in range(1, 4)]
来源:https://stackoverflow.com/questions/57309129/walrus-operator-example-in-pep572