我至少看到以下选项(按提高效率排序):
只是可读的 Pythonic 方式
python 的一个优点是您可以编写这些表达式,非常类似于用数学编写的方式。在您的情况下,您希望 sum 超过 iterable 的数字:
f = sum(
3 * gamma * H[i] * (
R + (
sum(
H[j] * np.tan(alpha[j])
for j in range(i+1)
)
)
)**2
for i in range(n)
)
缓存内部总和
在你的情况下,内部总和
sum(
H[j] * np.tan(alpha[j])
for j in range(i+1)
)
被计算多次,而它只是在每次迭代中递增。让我们将这个术语称为inner_sum(index)。那么inner_sum(index-1)已经在之前的迭代中计算过了。因此,当我们在每次迭代中重新计算它时,我们会浪费时间。一种方法是使inner_sum 成为一个函数并缓存其先前的结果。为此,我们可以使用functools.cache:
from functools import cache
@cache
def inner_sum(index: int) -> float:
if not index:
return H[0] * np.tan(alpha[0])
return inner_sum(H, index - 1) + H[index] * np.tan(alpha[index])
现在,我们可以写:
f = sum(
3 * gamma * H[i] * (
R + inner_sum(i)
)**2
for i in range(n)
)
使用生成器生成部分和
这仍然不是内存效率的,因为我们将所有 H[i] for i inner_sum_previous 中。或者你可以让inner_sum 一个正确的generator 一个接一个地吐出(实际上是:yielding)部分总和:
from typing import Generator
def partial_sum() -> Generator[float, None, None]:
partsum = 0
index = 0
while True:
try:
partsum += H[index] * np.tan(alpha[index])
yield partsum
index += 1
except IndexError:
raise StopIteration
有了这个,我们就可以写了;
partial_sum_generator = partial_sum()
f = sum(
3 * gamma * H[i] * (
R + next(partial_sum_generator)
)**2
for i in range(n)
)