在var=func()中,是立即计算func()还是在需要var时计算?

2024-06-02 06:40:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码

def isIt(arg):
    isA = funcA(arg)
    isB = funcB(arg)

    return (isA and isB)

其中funcB()在计算上比funcA要昂贵得多,并且在超过一半的情况下funcA()为False。你知道吗

因此,如果我让python只在funcA为True时调用funcB是有意义的

def isIt(arg):
    return (funcA(arg) and funcB(arg))

如果考虑到资源消耗,这两种功能是否相同?如果funcB()是生成器上的任意()呢?你知道吗

编辑1: 我打算像第一个代码那样编写,funcA()和funcB()的参数(不是arg)相当长,足以破坏可读性。你知道吗

另外,我刚刚意识到我可以用两个局部函数代替变量来达到和第二个代码一样的效果。你知道吗


Tags: and代码falsetruereturndefarg情况
3条回答

Are those two function same if resourse consumption is taken into account?

它们在功能上不一样。你似乎已经理解了这个问题,所以我不太清楚你在怀疑什么,但这在考虑资源消耗时尤其重要:

def isIt(arg):
    lightweightResult = lightweightFunction(arg)
    expensiveResult = superExpensiveFunction(arg)

    // obviously you can use both results here, so both have been computed.


    // return the values directly, no further computation done here:
    return (lightweightResult and expensiveResult)

这样做的一个原因是,如果您需要expensiveResult进行其他操作,或者总是需要调用superExpensiveFunction,例如某些资源的初始值设定项。你知道吗

在第二种情况下,如您所描述的,funcB(arg)仅在funcA(arg)求值为true(返回truthy值)时才求值。这称为short circuiting

def isIt(arg):
    return (lightweightFunction(arg) and superExpensiveFunction(arg))

众所周知,短路是防止不必要执行的好方法。你知道吗

What if funcB() is any() on a generator?

除非调用任何函数,否则它永远不会运行生成器。生成器已经是一种防止不必要执行的好方法,因为它们是惰性评估的。我认为短路和发电机在这种情况下是很好的结合。你知道吗

正如在Blkknght的注释中所指出的,值得注意的是any()all()也有短路,因此在生成器中,生成器的求值将仅限于确认结果的元素(all上为false,any上为true)。您可以在python.org...#all看到代码。你知道吗

我会把它写成

def isIt(arg):
    if not funcA(arg):
        return False
    return funcB(arg)

这有点长,但更符合Python哲学。你知道吗

编辑:从五行改为三行。你知道吗

它们不是等价的。第一个将在每种情况下同时调用funcAfuncB。只有当funcA的结果不真实时,第二个函数才会调用funcB,如逻辑或短路。你知道吗

相关问题 更多 >