一个解决方案(如果你有重复的 x 值最好)是记住函数 f,即创建一个包装函数来保存调用函数的参数并保存它,而不是在询问相同的值时返回它.
一个非常简单的实现如下:
storage = {}
def memoized(value):
if value not in storage:
storage[value] = f(value)
return storage[value]
[memoized(x) for x in l if memoized(x)]
然后在列表理解中使用这个函数。这种方法在两种情况下有效,一种是理论的,一种是实际的。第一个是函数f应该是确定性的,即在给定相同输入的情况下返回相同的结果,另一个是对象x可以用作字典键。如果第一个无效,则应根据定义每次重新计算 f ,而如果第二个失败,则可以使用一些更健壮的方法。
你可以在网上找到很多 memoization 的实现,我认为新版本的 python 也包含了一些东西。
附带说明一下,永远不要使用小 L 作为变量名,这是一个坏习惯,因为它可能与某些终端上的 i 或 1 混淆。
编辑:
正如所评论的,使用生成器理解(以避免创建无用的重复临时对象)的可能解决方案将是以下表达式:
[g(x, fx) for x, fx in ((x,f(x)) for x in l) if fx]
考虑到 f 的计算成本、原始列表中的重复次数和您所使用的内存,您需要权衡您的选择。记忆化在空间速度上进行了权衡,这意味着它会跟踪保存它的每个结果,因此如果您有大量列表,则在内存占用方面可能会变得昂贵。