Python 列表理解与重复计算

Python 列表理解与重复计算,python,list-comprehension,Python,List Comprehension,我目前正在用Python处理ProjectEulerProblem 53。解决方案非常简单,但涉及以下列表理解: [scipy.misc.comb(n, r, exact=True) for n in range(1,maxn+1) for r in range(0,n+1) if scipy.misc.comb(n, r, exact=True) > threshold] 但我担心的是,每次迭代都会调用scipy.misc.comb()函数两次。有没有办法用某种引用来代替它的一个

我目前正在用Python处理ProjectEulerProblem 53。解决方案非常简单,但涉及以下列表理解:

[scipy.misc.comb(n, r, exact=True)
 for n in range(1,maxn+1)
 for r in range(0,n+1)
 if scipy.misc.comb(n, r, exact=True) > threshold]

但我担心的是,每次迭代都会调用scipy.misc.comb()函数两次。有没有办法用某种引用来代替它的一个或其他出现;或者,解释器是否足够聪明,能够意识到这两个实例的计算结果相同?

您可以将
scipy.misc.comb()
函数放入生成器表达式中:

[comb for comb in 
    (scipy.misc.comb(n, r, exact=True) 
     for n in range(1,maxn+1) for r in range(0,n+1))
 if comb > threshold]
在生成器上,每次迭代只计算一次

将生成器表达式放入一个单独的变量中可以更清楚地说明这一点:

calculated = (scipy.misc.comb(n, r, exact=True) 
              for n in range(1,maxn+1) for r in range(0,n+1))
[comb for comb in calculated if comb > threshold]

将其视为传送带;
computed
生成器仅在列表理解对其进行迭代时生成其输出。

解释器不够聪明,无法确定两个函数调用的计算结果是相同的。但是,函数本身可能被写入缓存结果。@sweeneyrod:相反,解释器很聪明,它不可能知道每次调用函数时都会产生相同的结果,即使使用相同的参数也是如此。