发布于2021-10-05 20:56 阅读(1392) 评论(0) 点赞(22) 收藏(4)
在学习javascript和python的过程中,我们通常会接触到map
、filter
、reduce
之类的一等公民高阶函数。理解map
和filter
是相对简单的事情,但理解reduce
的话还是需要一番推敲。正值十一假期,今天这篇文章就好好讲讲reduce
这个东西
我们首先以python为例,看一段reduce
程序的操作:
from functools import reduce
from dataclasses import dataclass
@dataclass
class Stats:
product: int = 1
sum: int = 0
num: int = 0
avg: float = 0.0
max: int = -1e9
min: int = 1e9
def reducer(cur_state, cur_element):
assert isinstance(cur_state, Stats)
print('processing element %d, current stats: %s' % (cur_element, cur_state))
cur_state.num += 1
cur_state.sum += cur_element
cur_state.product *= cur_element
cur_state.avg = float(cur_state.sum) / float(cur_state.num)
if cur_element > cur_state.max:
cur_state.max = cur_element
if cur_element < cur_state.min:
cur_state.min = cur_element
return cur_state
def main():
ints = [1, 5, 2, 3, 4]
reduced_stats = reduce(reducer, ints, Stats())
print(reduced_stats)
if __name__ == '__main__':
main()
这段程序里的操作,输入是一组整数,最后输出来的是这组整数的统计数据,比如总和sum
、积product
、最大最小值等等。实现这个统计操作,就可以用reduce
。在functools
库中,我们可以看到reduce
的定义:
_initial_missing = object()
def reduce(function, sequence, initial=_initial_missing):
"""
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
"""
it = iter(sequence)
if initial is _initial_missing:
try:
value = next(it)
except StopIteration:
raise TypeError("reduce() of empty sequence with no initial value") from None
else:
value = initial
for element in it:
value = function(value, element)
return value
try:
from _functools import reduce
except ImportError:
pass
这段代码简单易懂,我们可以看到reduce
函数需要一个初始值initial
,并定义一个会变化的当前值value
,然后会在遍历我们定义的sequence
序列的过程中,不断用function
(叫成reducer
更加贴切)依据当前遍历到的元素element
来更新当前值value
(的内部状态),并在最后返回最终的value
。
所以很显然,reduce
这个函数,针对一个特定的sequence
,返回值应当反映这个sequence
的某样(些)属性。这便是reduce
的意义所在了。
学过javascript的同学,会经常在网上资料看到reduce
的翻译叫做归并
,个人认为归并
这个词已经翻译的非常贴切了,一时间也找不到更好的信达雅的表达。当然如果我们去检索英文百科,甚至还可以了解到更多的信息。
reduce
是函数式编程的一个代表。我们检索函数式编程的维基百科,里面可以跳到reduce
的百科,我们发现其实会跳到另一个单词的百科,叫做fold
从fold
以及衍生词汇reduce
、accumulate
、aggregation
可以看到,这类操作其实用中文翻译除了叫归并
以外,叫累积
、聚合
也不过分(嗯这里又可以看到我们的老朋友mongodb,aggregation
跟accumulate
关键词都上架了),都是代表着一种遍历所有元素值,不断合并计算,得出最终结果
的运算操作。fold
反过来叫做unfold
,对应的也是另一个单词的百科,叫做Anamorphism
。Anamorphism
本意是岩石变性
、渐变
,但在计算机领域,作为和fold
相反的运算方式,是一个会不断根据当前值来生成下一个值,从而展开
出来一个sequence
的生成器generator
(所以这种运算通俗的说,就翻译为展开
即可,跟unfold
也很搭)。我们熟悉的斐波那契数列,就可以用unfold
/Anamorphism
代表的运算方式生成。初始值为(0,1),根据(0,1)生成下一个数字1,根据(1,1)生成下一个数字2。这样不断展开
下去,我们就可以得到特定长度的斐波那契数列了。
作者:代码搬运工
链接:http://www.qianduanheidong.com/blog/article/198115/01f967e8e21132f7fff4/
来源:前端黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 前端黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-3
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!