转载:python代码:reduce函数
#!/usr/bin/python # -*- coding: UTF-8 -*- """ @author: @file:test02.py @time:2022-03-20 21:50 """ # # from 书《Python核心编程(第二版).pdf》,作者:Wesley J. Chun # # 如果我们想要试着用纯Python实现reduce()。它可能会是这样: # def reduce(bin_func, seq, init=None): # lseq = list(seq) # convert to list # if init is None: # initializer? # res = lseq.pop(0) # no # else: # res = init # yes # for item in lseq: # reduce sequence # res = bin_func(res, item) # apply function # return res # return result # # ==== # 文章作者:作者:Panda Fang # 文章原始链接:https://www.cnblogs.com/lonkiss/p/understanding-python-reduce-function.html from functools import reduce """ # 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. 从左到右对一个序列的项累计地应用有两个参数的函数,以此合并序列到一个单一值。 例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 计算的就是((((1+2)+3)+4)+5)。 如果提供了 initial 参数,计算时它将被放在序列的所有项前面,如果序列是空的,它也就是计算的默认结果值了 序列 其实就是python中 tuple list dictionary string 以及其他可迭代物,别的编程语言可能有数组。 reduce 有 三个参数 function 有两个参数的函数, 必需参数 sequence tuple ,list ,dictionary, string等可迭代物,必需参数 initial 初始值, 可选参数 reduce的工作过程是 :在迭代sequence(tuple ,list ,dictionary, string等可迭代物)的过程中, 首先把 前两个元素传给 函数参数,函数加工后,然后把得到的结果和第三个元素作为两个参数传给函数参数, 函数加工后得到的结果又和第四个元素作为两个参数传给函数参数,依次类推。 如果传入了 initial 值, 那么首先传的就不是 sequence 的第一个和第二个元素, 而是 initial值和 第一个元素。经过这样的累计计算之后合并序列到一个单一返回值。 """ # # 例子1:求和 # def add(x, y): # return x + y # # # result = reduce(add, [1, 2, 3, 4]) # print(result) # 10 # # 上面这段 reduce 代码,其实就相当于 1 + 2 + 3 + 4 = 10, 如果把加号改成乘号, 就成了阶乘了 # # 当然 仅仅是求和的话还有更简单的方法,即:sum([1,2,3,4]) # 10 # # ---- # # 例子2:把一个整数列表拼成整数 # result = reduce(lambda x, y: x * 10 + y, [1, 2, 3, 4, 5]) # print(result) # 12345 # # ---- # # 例子3: # scientists = ({'name': 'Alan Turing', 'age': 105, 'gender': 'male'}, # {'name': 'Dennis Ritchie', 'age': 76, 'gender': 'male'}, # {'name': 'Ada Lovelace', 'age': 202, 'gender': 'female'}, # {'name': 'Frances E. Allen', 'age': 84, 'gender': 'female'}) # # # def reducer(accumulator, value): # # 因为第二次调用reducer的时候,此时accumulator已经变成181了,再调用accumulator['age']就出错了 # # total = accumulator['age'] + value['age'] # TypeError: 'int' object is not subscriptable # total = accumulator + value['age'] # return total # # # # result = reduce(reducer, scientists) # TypeError: 'int' object is not subscriptable # result = reduce(reducer, scientists, 0) # 0为初始值 # print(result) # 467 # # 这个仍然也可以用 sum 来更简单的完成: sum([x['age'] for x in scientists ]) # # ---- # # 例子4:按性别分组 # scientists = ({'name': 'Alan Turing', 'age': 105, 'gender': 'male'}, # {'name': 'Dennis Ritchie', 'age': 76, 'gender': 'male'}, # {'name': 'Ada Lovelace', 'age': 202, 'gender': 'female'}, # {'name': 'Frances E. Allen', 'age': 84, 'gender': 'female'}) # # # def group_by_gender(accumulator, value): # accumulator[value['gender']].append(value['name']) # return accumulator # # 方法一:在 reduce 的初始值参数传入了一个dictionary,key为事先写死的。 # # 缺点:这样写 key 可能出错。 # grouped = reduce(group_by_gender, scientists, {'male': [], 'female': []}) # print(grouped) # {'male': ['Alan Turing', 'Dennis Ritchie'], 'female': ['Ada Lovelace', 'Frances E. Allen']} # # 方法二:运行时动态插入key # import collections # grouped = reduce(group_by_gender, scientists, collections.defaultdict(list)) # print(grouped) # defaultdict(<class 'list'>, {'male': ['Alan Turing', 'Dennis Ritchie'], 'female': ['Ada Lovelace', 'Frances E. Allen']}) # # 方法三:用 pythonic way 去解决 # import itertools # grouped = {item[0]: list(item[1]) # for item in itertools.groupby(scientists, lambda x: x['gender'])} # print(grouped) # {'male': [{'name': 'Alan Turing', 'age': 105, 'gender': 'male'}, {'name': 'Dennis Ritchie', 'age': 76, 'gender': 'male'}], 'female': [{'name': 'Ada Lovelace', 'age': 202, 'gender': 'female'}, {'name': 'Frances E. Allen', 'age': 84, 'gender': 'female'}]} # # 方法四: # grouped = reduce(lambda acc, val: {**acc, **{val['gender']: acc[val['gender']] + [val['name']]}}, scientists, {'male': [], 'female': []}) # print(grouped) # {'male': ['Alan Turing', 'Dennis Ritchie'], 'female': ['Ada Lovelace', 'Frances E. Allen']} # # **acc, **{val['gneder']... 这里使用了 dictionary merge syntax , 从 python 3.5 开始引入, 详情请看 PEP 448 - Additional Unpacking Generalizations # # 怎么使用可以参考这个 python - How to merge two dictionaries in a single expression? - Stack Overflow # # ----