带有重复计算的列表推导式

4

我目前在使用Python解决欧拉计划第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()函数两次。有没有办法用某种引用替换其中一个或另一个出现的实例; 或者解释器是否足够聪明,能够意识到这两个实例将评估为相同的结果?


解释器并不足够聪明,无法计算出两个函数调用将评估为相同的结果。但是,函数本身可能被编写为缓存结果。 - rlms
2
@sweeneyrod:相反,解释器足够聪明,知道它不可能知道每次调用函数时即使使用相同的参数也会产生相同的结果。 - Martijn Pieters
1个回答

6
您可以将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]

将其视为传送带;只有在列表推导式迭代时,calculated生成器才会产生其输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接