python开发-reduce函数的使用

python中的reduce函数也是个常用的函数,在python3中该函数已被移到functools模块中。
reduce接收两个参数:reduce(参数1, 参数2);参数1是一个函数,参数2是一个数据集合。
简单例子如下:


In [1]: from functools import reduce

In [2]: def func(x, y):
   ...:     return x * y
   ...:
   ...:
In [3]: reduce(func, [1, 2, 3, 4, 5])
Out[3]: 120

下面看一个复杂点的需求:


l1 = [[{"pid": 12, "value": 1},{"pid": 13, "value": 2}],
          [{"pid": 13, "value": 3},{"pid": 12, "value": 1}],
          [{"pid": 12, "value": 1},{"pid": 17, "value": 4}],
          [{"pid": 10, "value": 1},{"pid": 13, "value": 5}],
          [{"pid": 13, "value": 6},{"pid": 12, "value": 1}]
]
res_data = [{"pid": 12, "value": 10}, {"pid": 13, "value": 11}]

将l1中的pid与res_data中pid相同的value加到res_data中,结果是:


[{'pid': 12, 'value': 14}, {'pid': 13, 'value': 27}]

这个使用for循环也能实现,但是要循环多次。下面是使用reduce的实现:


from functools import reduce


def test1(res, b):
    print("test1 res:", res)
    print("b:", b)
    if res["pid"] == b["pid"]:
        # 具体要执行的操作:value值相加
        return dict(pid=res["pid"], value=res["value"] + b["value"])
    return res


def test2(res, list1):
    print("test2 res:", res)
    ret1 = reduce(test1, list1, res)
    return ret1


if __name__ == '__main__':
    l1 = [[{"pid": 12, "value": 1},{"pid": 13, "value": 2}],
          [{"pid": 13, "value": 3},{"pid": 12, "value": 1}],
          [{"pid": 12, "value": 1},{"pid": 17, "value": 4}],
          [{"pid": 10, "value": 1},{"pid": 13, "value": 5}],
          [{"pid": 13, "value": 6},{"pid": 12, "value": 1}]
    ]
    res_data = [{"pid": 12, "value": 10}, {"pid": 13, "value": 11}]
    ret_list = list()
    for res in res_data:
        print("res:", res)
        ret = reduce(test2, l1, res)
        ret_list.append(ret)
    print("ret_list:", ret_list)

打印出中间结果,看一下这个嵌套reduce的执行流程:


res: {'pid': 12, 'value': 10}
test2 res: {'pid': 12, 'value': 10}
test1 res: {'pid': 12, 'value': 10}
b: {'pid': 12, 'value': 1}
test1 res: {'pid': 12, 'value': 11}
b: {'pid': 13, 'value': 2}
test2 res: {'pid': 12, 'value': 11}
test1 res: {'pid': 12, 'value': 11}
b: {'pid': 13, 'value': 3}
test1 res: {'pid': 12, 'value': 11}
b: {'pid': 12, 'value': 1}
test2 res: {'pid': 12, 'value': 12}
test1 res: {'pid': 12, 'value': 12}
b: {'pid': 12, 'value': 1}
test1 res: {'pid': 12, 'value': 13}
b: {'pid': 17, 'value': 4}
test2 res: {'pid': 12, 'value': 13}
test1 res: {'pid': 12, 'value': 13}
b: {'pid': 10, 'value': 1}
test1 res: {'pid': 12, 'value': 13}
b: {'pid': 13, 'value': 5}
test2 res: {'pid': 12, 'value': 13}
test1 res: {'pid': 12, 'value': 13}
b: {'pid': 13, 'value': 6}
test1 res: {'pid': 12, 'value': 13}
b: {'pid': 12, 'value': 1}
res: {'pid': 13, 'value': 11}
test2 res: {'pid': 13, 'value': 11}
test1 res: {'pid': 13, 'value': 11}
b: {'pid': 12, 'value': 1}
test1 res: {'pid': 13, 'value': 11}
b: {'pid': 13, 'value': 2}
test2 res: {'pid': 13, 'value': 13}
test1 res: {'pid': 13, 'value': 13}
b: {'pid': 13, 'value': 3}
test1 res: {'pid': 13, 'value': 16}
b: {'pid': 12, 'value': 1}
test2 res: {'pid': 13, 'value': 16}
test1 res: {'pid': 13, 'value': 16}
b: {'pid': 12, 'value': 1}
test1 res: {'pid': 13, 'value': 16}
b: {'pid': 17, 'value': 4}
test2 res: {'pid': 13, 'value': 16}
test1 res: {'pid': 13, 'value': 16}
b: {'pid': 10, 'value': 1}
test1 res: {'pid': 13, 'value': 16}
b: {'pid': 13, 'value': 5}
test2 res: {'pid': 13, 'value': 21}
test1 res: {'pid': 13, 'value': 21}
b: {'pid': 13, 'value': 6}
test1 res: {'pid': 13, 'value': 27}
b: {'pid': 12, 'value': 1}
ret_list: [{'pid': 12, 'value': 14}, {'pid': 13, 'value': 27}]

通过上面的中间结果,可以容易的看出嵌套reduce的执行流程。

对reduce应用来说,上面只是一个小例子。在处理复杂的数据操作时,也可以用reduce。