通过积累进行减少的Pythonic方法是什么?
例如,选择R
' Reduce()
。给定一个列表和一个任意的lambda函数,它允许通过设置accumulate=T
产生累积结果的向量而不是最终结果。一个简单的乘法作为lambda函数的例子是(取自this answer):
Reduce(`*`, x=list(5,4,3,2), accumulate=TRUE)
# [1] 5 20 60 120
重要的是可以使用任意lambda函数(如lambda x, y: ...
),因此可以使用例如# the source list
l = [0.5, 0.9, 0.8, 0.1, 0.1, 0.9]
# the lambda function for aggregation can be arbitrary
# this one is just made up for the example
func = lambda x, y: x * 0.65 + y * 0.35
# the accumulated reduce:
# a) the target list with initializer value hardcoded
l2 = [l[0]]
# b) the loop
for i in range(1, len(l)):
l2 += [func(
l2[i-1], # last value in l2
l[i] # new value from l
)]
}的解决方案。只使用总和,乘法,否则不会做的伎俩。我无法想出一个Pythonic解决方案来做到这一点,例如Python的itertools
或functools
,但可能有办法。尽管还有许多关于使用Python进行减少和特别积累的其他问题和答案,但到目前为止我还没有找到一个通用的答案。
使用循环执行带有任意lambda函数的累积reduce的非Pythonic示例可能如下所示:
.subscribe(res-> {
//success case
},
t -> {
if (t instanceof HttpException) {
if (((HttpException) t).code() == 422) {
String errorResponse=((HttpException) t).response().errorBody().string();
//your validations
}
} else {
t.printStackTrace();
}
});
那么:你如何用Pythonic方式进行累积和任意lambda函数的减少?
答案 0 :(得分:2)
在Python 3中(在3.2中引入,能够传递3.3中添加的功能)这已在itertools.accumulate
中实现。只需使用它:
from itertools import accumulate
list(accumulate([5, 4, 3, 2], lambda a, b: a*b))
# [5, 20, 60, 120]
如果您使用的是早期的Python版本,或者想要自己实现它,并且您真的想要任意lambda
(需要两个参数)才能工作,那么您可以使用在上述文件:
def accumulate(iterable, func=operator.add):
'Return running totals'
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable)
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = func(total, element)
yield total
用法与上述完全相同。
如果您使用numpy
,则存在更快的解决方案,至少对于所有numpy.ufunc
来说都是如此。这些功能基本上与标准库模块math
提供的功能相同,然后是一些功能。您可以找到完整列表here。
每个numpy.ufunc
都有accumulate
方法,因此您可以这样做:
import numpy as np
np.multiply.accumulate([5, 4, 3, 2])
# array([ 5, 20, 60, 120])