我想知道是否有人有一个很好的干净的Pythonic和有效的技术来实现在结果中涉及保护中相同表达的理解。 需要明确的是,请考虑以下简单示例:
config.htmlEncodeOutput = false;
config.entities = false;
这将打印
def f(a):
print "Calling", a
return a + 1
print [ f(v) for v in xrange(3) if f(v) > 1 ]
证明大多数元素都会调用f两次。这很好,如果f有副作用,我们想要什么,但如果f是一些没有副作用的昂贵操作,重复调用是不可取的。但是对于每个元素只调用f一次的解决方案对我来说似乎笨拙/冗长:
Calling 0
Calling 1
Calling 1
Calling 2
Calling 2
[2, 3]
即使它被缩减为一行
intermediate = ( f(v) for v in xrange(3) )
print [ r for r in intermediate if r > 1 ]
那么,任何人都能想出更好的东西吗?
答案 0 :(得分:2)
您可以使用 filter()
功能:
filter(lambda x: x > 1, [ f(v) for v in xrange(3)])
但这与你上一次建议的解决方案一样冗长。
答案 1 :(得分:1)
如何记忆f
,例如:?
def f(...): ...
def some_or_other():
f = functools.lru_cache(1)(f)
[ f(v) for v in xrange(3) if f(v) > 1 ]
在本地进行记事,使用您的呼叫站点的范围具有以下优点:一旦some_or_other()
返回,“备忘录”内存将被垃圾收集,您不必担心对v
的引用已传递给f()
。
由于它是本地的,备忘录大小限制1就足够了。
在简单的情况下,您还可以全局地记住f
:
@functools.lru_cache()
def f(...): ...
[ f(v) for v in xrange(3) if f(v) > 1 ]
答案 2 :(得分:0)