我对清单的理解大致如下:
[f(x) for x in l if f(x)]
其中l是一个列表,f(x)是一个昂贵的函数,它返回一个列表。
我想避免每出现一个非空的f(x)就计算f(x)两次。有没有办法把它的输出保存在列表理解中?
我可以删除最后一个条件,生成整个列表,然后将其删减,但这似乎是浪费。
编辑:
提出了两种基本方法:
一个内在的发电机理解:
[y for y in (f(x) for x in l) if y]
或者备忘录。
我认为内部生成器对于上述问题的理解是优雅的。事实上,我简化了这个问题,想说清楚,我真的想:
[g(x, f(x)) for x in l if f(x)]
对于这种更复杂的情况,我认为记忆产生了一个更清晰的最终结果。
会的。
你应该用一个备忘录装饰器。这里有一个有趣的link。
使用链接和“代码”中的备忘录:
一个解决方案(如果x值重复,最好是将函数f记住,即创建一个包装函数,保存调用函数的参数并保存它,而不是在要求相同的值时返回它。
一个非常简单的实现如下:
然后在列表理解中使用这个函数。该方法在理论和实际两个条件下都是有效的。第一个是函数f应该是确定性的,即给定相同的输入返回相同的结果,第二个是对象x可以用作字典键。如果第一个方法无效,则应根据定义每次重新计算f,而如果第二个方法失败,则可以使用稍微更健壮的方法。
你可以在网络上找到很多回忆录的实现,我认为python的新版本也包含了一些东西。
另一方面,不要使用小的L作为变量名,这是一个坏习惯,因为在某些终端上,它可能会与i或1混淆。
编辑:
如前所述,使用生成器理解(以避免创建无用的重复临时对象)的一个可能的解决方案是:
考虑到f的计算成本、原始列表中的重复次数和可配置的内存,您需要权衡您的选择。记忆录可以在空间速度上进行权衡,这意味着它会记录保存的每个结果,因此如果你有大量的列表,那么在内存占用方面可能会变得昂贵。
相关问题 更多 >
编程相关推荐