一个解决方案(如果你有重复的 x 值,那么这是最好的)是对函数 f 进行记忆化处理,即创建一个包装函数来保存调用该函数的参数,并将其保存起来,然后在请求相同值时返回它。
以下是一个非常简单的实现:
如果您有重复的 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,而如果第二个条件失败,则可以使用一些稍微更强大的方法。
您可以在网络上找到许多备忘录化的实现,我认为新版本的Python也包括了一些内容。
顺便提一句,永远不要使用小写字母L作为变量名,因为它可能会在某些终端上与i或1混淆,这是一种不好的习惯。
编辑:
正如评论所述,使用生成器推导式(以避免创建无用的重复临时变量)的可能解决方案是此表达式:
[g(x, fx) for x, fx in ((x,f(x)) for x in l) if fx]
考虑到函数f的计算成本、原始列表中重复元素的数量以及您拥有的内存,您需要权衡选择。记忆化(Memoization)进行了一种空间-速度权衡,这意味着它会跟踪每个结果并将其保存下来,因此如果您有巨大的列表,则可能会在内存占用方面变得昂贵。
[g(x, fx) for x, fx in ((x,f(x)) for x in l) if fx]
。主要问题是x是否有任何重复。 - EnricoGiampieri