gpt4 book ai didi

python - 我可以在 Python 列表推导中为表达式取别名以防止它们被多次评估吗?

转载 作者:IT老高 更新时间:2023-10-28 21:18:45 25 4
gpt4 key购买 nike

我发现自己经常想像这样编写 Python 列表推导:

nearbyPoints = [(n, delta(n,x)) for n in allPoints if delta(n,x)<=radius]

希望能提供一些背景信息来说明我为什么要这样做,但是也是需要计算/比较多个值的情况元素:

newlist = [(x,f(x),g(f(x))) for x in bigList if f(x)<p and g(f(x))<q]

所以我有两个问题:

  1. 所有这些函数会被多次评估还是缓存结果?语言是指定的还是特定于实现的?我现在使用的是 2.6,但 3.x 会有所不同吗?
  2. 有没有更简洁的写法?有时 f 和 g 是长表达式并且重复很容易出错并且看起来很乱。我真的很想能够写这个:
newList = [(x,a=f(x),b=g(a)) for x in bigList if a<p and b<q]

但这不起作用。有充分的理由不支持这种语法吗?能可以通过 this 之类的方式完成?还是我只需要使用多个 listcomps 或 for 循环?

最佳答案

更新: walrus-operator := 是在 Python 3.8 中引入的,它分配一个变量,但也计算分配的值。根据@MartijnVanAttekum 的回答。我建议在项目中使用它之前等待一年左右,因为 Python 3.6 和 3.7 仍然是相当主流的,但它是一个比我下面的别名建议更好的解决方案。

我有一个 hack 在列表/字典推导中创建别名。您可以使用 for alias_name in [alias_value] 技巧。例如你有这个昂贵的功能:

def expensive_function(x):
print("called the very expensive function, that will be $2")
return x*x + x

还有一些数据:

data = [4, 7, 3, 7, 2, 3, 4, 7, 3, 1, 1 ,1]

然后你想对每个元素应用昂贵的函数,并基于它进行过滤。你要做的是:

result = [
(x, expensive)
for x in data
for expensive in [expensive_function(x)] #alias
if expensive > 3
]

print(result)

second-for 只会遍历大小为 1 的列表,从而有效地使其成为别名。输出将显示昂贵的函数被调用了 12 次,每个数据元素只调用一次。然而,函数的结果(最多)被使用了两次,一次用于过滤器,一次可能用于输出。

请始终确保像我一样使用多行来布局此类理解,并将#alias 附加到别名所在的行。如果您使用别名,理解会变得非常复杂,您应该帮助您的代码的 future 读者了解您正在做的事情。这不是 perl,你知道 ;)。

为了完整起见,输出:

called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
called the very expensive function, that will be $2
[(4, 20), (7, 56), (3, 12), (7, 56), (2, 6), (3, 12), (4, 20), (7, 56), (3, 12)]

代码:http://ideone.com/7mUQUt

关于python - 我可以在 Python 列表推导中为表达式取别名以防止它们被多次评估吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4840392/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com