Python 两次操作累积在一起

Python 两次操作累积在一起,python,functional-programming,Python,Functional Programming,我试图将以下循环转换为accumulate()调用,但失败了: total = 0 for h in heat_values: total += h total -= total*0.25 如何累积h值,包括0.25衰减因子 背景:我想做这个只是为了好玩的练习,用函数式编程方式模拟同步加热和冷却过程(加法操作是加热步骤,减法操作是冷却步骤)。我想获得累积值来绘制流程的值。简而言之,您不需要累积对现有的iterable类型进行操作,例如每日生产数量列表,返回其运行总数。你有一个递

我试图将以下循环转换为
accumulate()
调用,但失败了:

total = 0
for h in heat_values:
    total += h
    total -= total*0.25
如何累积h值,包括0.25衰减因子


背景:我想做这个只是为了好玩的练习,用函数式编程方式模拟同步加热和冷却过程(加法操作是加热步骤,减法操作是冷却步骤)。我想获得累积值来绘制流程的值。

简而言之,您不需要累积对现有的iterable类型进行操作,例如每日生产数量列表,返回其运行总数。你有一个递归关系,而不是一个现成的可数。问题在于,总计取决于对先前值的衰减操作


如果你想让它成为一个单行程序,我建议你使用reduce,它允许你指定reduce函数——即你自己设计的lambda函数。

简而言之,你不需要累积对现有的iterable类型进行操作,例如每日生产数量列表,返回其运行总数。你有一个递归关系,而不是一个现成的可数。问题在于,总计取决于对先前值的衰减操作


如果你想让它成为一个单行程序,我建议你使用reduce,它允许你指定缩减函数——即你自己设计的lambda函数。

除非我的数学或推理不正确,否则这就是你使用
累加
实现的方法:

heatvalues = [20, 30, 40, 50]

list(accumulate(heatvalues, lambda x, y: (x+y)*.75))

>>>[20, 37.5, 58.125, 81.09375]
编辑:如果只需要最后一个元素,即总数,则它将变为:

list(accumulate(heatvalues, lambda x, y: (x+y)*.75))[-1]

>>>81.09375

除非我的数学或推理不正确,否则这就是使用
累计
实现的方法:

heatvalues = [20, 30, 40, 50]

list(accumulate(heatvalues, lambda x, y: (x+y)*.75))

>>>[20, 37.5, 58.125, 81.09375]
编辑:如果只需要最后一个元素,即总数,则它将变为:

list(accumulate(heatvalues, lambda x, y: (x+y)*.75))[-1]

>>>81.09375
(2.x中的
reduce
)可以正常工作。
函数
按顺序获取两个参数,即当前累积值和序列中的新值

对于你的问题,减去.25等于乘以.75。这两种操作都是在添加新值后完成的。这应该行得通

from functools import reduce
def update(total, new):
    return .75 * (total + new)
total = reduce(update, heat_values, 0)
编辑:我写上述内容时没有注意到在3.2版的itertools中添加了
accumulate
,在3.3版中添加了
func
参数。文档没有指定
func
的两个参数的顺序,但它与
reduce
函数的顺序相同:累积值,新值。这是通过使用非对称更新表达式来验证的,例如
.75*可以使running_total+new_value
(2.x中的just
reduce
)起作用。
函数
按顺序获取两个参数,即当前累积值和序列中的新值

对于你的问题,减去.25等于乘以.75。这两种操作都是在添加新值后完成的。这应该行得通

from functools import reduce
def update(total, new):
    return .75 * (total + new)
total = reduce(update, heat_values, 0)

编辑:我写上述内容时没有注意到在3.2版的itertools中添加了
accumulate
,在3.3版中添加了
func
参数。文档没有指定
func
的两个参数的顺序,但它与
reduce
函数的顺序相同:累积值,新值。这是通过使用非对称更新表达式来验证的,例如
0.75*运行\u total+新\u value

total-=total*0.25
is
total*=0.75
,该表达式适用于
reduce(lambda h,total:+h)*0.75,heat\u value,0.0)
@dhke lambda表达式的签名是向后的。在这种特殊情况下,这无关紧要,因为total和h只是相加,相加是累加的。不过,如果函数是更现实的,
.75*total+h
@TerryJanReedy感谢您指出,
lambda-total,h:
当然是正确的顺序。
total-=total*0.25
total*=0.75
,它与
reduce(lambda-h,total:+h)*0.75,heat\u值,0.0)一起工作良好
@dhke lambda表达式的签名是向后的。在这种特殊情况下,这无关紧要,因为total和h只是相加,相加是累加的。不过,如果函数是更现实的,
.75*total+h
@TerryJanReedy感谢您指出,
lambda total,h:
的顺序当然是正确的。heat\u值是一个ready iterable,否则原始for循环就没有意义heat\u值是ready iterable,否则原始for循环就没有意义了如果你想要最后一个元素,你可以使用reduce而不是accumulate。我已经进行了编辑以适应这一点,我只是用他们试图使用的模块回答了OPs问题。所以要完成这个:
reduce(lambda x,y:(x+y)*.75,heat_值)
返回最终的合计值和
累计值(热值,λx,y:(x+y)*.75)
获取中间值,即我的目标值(用于绘图)。如果需要最后一个元素,请使用reduce而不是accumulate。我已经进行了编辑,以适应此情况,我只是用他们试图使用的模块回答OPs的问题。为了完成这个:
reduce(lambda x,y:(x+y)*.75,heat_值)
返回最终的总数,
累计(heat_值,lambda x,y:(x+y)*.75)
得到我想要的中间值(用于绘图)。