我可以在保留 lambda 表达式的同时删除双重评估吗
Can I remove double evaluation whilst keeping lambda expression
def bar(x):
# some expensive calculation
<snip>
foo = lambda(x): bar(x) if bar(x) > 10 else 0
不过这里我计算了两次foo。有没有办法仍然把它写成一个衬里,但避免双重评估。我试过了
foo = lambda(x): v if (v = bar(x)) > 10 else 0
但这不起作用。
预估:
foo = lambda(x): x if x > 10 else 0
result = foo(bar(x))
在这里您可以看到与您的代码有何相似之处:
lambda (x): foo(x) if foo(x) > 10 else 0 == (lambda(x): x if x > 10 else 0)(foo(x))
除非您创建某种可变状态对象或其他一些奇怪的技巧,否则您所寻求的是不可能的。
@Alakazam 的回答是巧妙而聪明的,使用它需要您自担风险。最好使用迭代器和 next
来避免额外的中间列表:
lambda x: next(res if res > 10 else 0 for res in (bar(x), ))
这里有 live example
只有当您的函数执行时间很长时才需要这样做,否则您不应该介意 运行 它两次。您不能使用 列表理解.
foo = lambda x: [res if res>10 else 0 for res in [bar(x)]][0]
是的,您可以避免在 lambda 中进行双重计算。但它真的很难看,你应该避免它。外观如下:
foo = lambda x: next(b if b > 10 else 0 for b in [bar(x)])
这是否易于阅读和理解?不,绝对不是。我不打算解释它;看看你能不能弄明白。这显然不是一个好的解决方案,那么您应该怎么做呢?您应该使用真正的函数而不是 lambda。
def foo(x):
b = bar(x)
return b if b > 10 else 0
这更容易阅读,也更清晰。
不妨再定义一个函数:
def bar(x):
# some expensive calculation
<snip>
def bar_threshold(x,t):
y = bar(x)
return y if y>t else 0
foo = lambda x: bar_threshold(x,10)
(或者重新定义bar,如果你发现自己只用threshold)
我试过制作一些函数装饰器/包装器...
def funcdec(func):
def inner(x):
if func(x) > 10:
return func(x)
else:
return 0
然后
@funcdec
def bar(x):
return x * 2
那我试试....:[=15=]
foo = lambda x: bar(x)
给我结果:
foo(2)
return 0
和
foo(10)
return 20
def bar(x):
# some expensive calculation
<snip>
foo = lambda(x): bar(x) if bar(x) > 10 else 0
不过这里我计算了两次foo。有没有办法仍然把它写成一个衬里,但避免双重评估。我试过了
foo = lambda(x): v if (v = bar(x)) > 10 else 0
但这不起作用。
预估:
foo = lambda(x): x if x > 10 else 0
result = foo(bar(x))
在这里您可以看到与您的代码有何相似之处:
lambda (x): foo(x) if foo(x) > 10 else 0 == (lambda(x): x if x > 10 else 0)(foo(x))
除非您创建某种可变状态对象或其他一些奇怪的技巧,否则您所寻求的是不可能的。
@Alakazam 的回答是巧妙而聪明的,使用它需要您自担风险。最好使用迭代器和 next
来避免额外的中间列表:
lambda x: next(res if res > 10 else 0 for res in (bar(x), ))
这里有 live example
只有当您的函数执行时间很长时才需要这样做,否则您不应该介意 运行 它两次。您不能使用 列表理解.
foo = lambda x: [res if res>10 else 0 for res in [bar(x)]][0]
是的,您可以避免在 lambda 中进行双重计算。但它真的很难看,你应该避免它。外观如下:
foo = lambda x: next(b if b > 10 else 0 for b in [bar(x)])
这是否易于阅读和理解?不,绝对不是。我不打算解释它;看看你能不能弄明白。这显然不是一个好的解决方案,那么您应该怎么做呢?您应该使用真正的函数而不是 lambda。
def foo(x):
b = bar(x)
return b if b > 10 else 0
这更容易阅读,也更清晰。
不妨再定义一个函数:
def bar(x):
# some expensive calculation
<snip>
def bar_threshold(x,t):
y = bar(x)
return y if y>t else 0
foo = lambda x: bar_threshold(x,10)
(或者重新定义bar,如果你发现自己只用threshold)
我试过制作一些函数装饰器/包装器...
def funcdec(func):
def inner(x):
if func(x) > 10:
return func(x)
else:
return 0
然后
@funcdec
def bar(x):
return x * 2
那我试试....:[=15=]
foo = lambda x: bar(x)
给我结果:
foo(2)
return 0 和
foo(10)
return 20