python中的reduce内建函数使用方法指南


Posted in Python onAugust 31, 2014

官方解释:

Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned. Roughly equivalent to:

意思就是说:将一个可迭代的对象应用到一个带有两个参数的方法上,我们称之为appFun,遍历这个可迭代对象,将其中的元素依次作为appFun的参数,但这个函数有两个参数,作为哪个参数呢?有这样的规则,看一下下面reduce方法的实现,有三个参数,第一个参数就是上面说的appFun,第二个参数就是那个可迭代的对象,而第三个呢?当调用reduce方法的时候给出了initializer这个参数,那么第一次调用appFun的时候这个参数值就作为第一个参数,而可迭代对象的元素依次作为appFun的第二个参数;如果调用reduce的时候没有给出initializer这个参数,那么第一次调用appFun的时候,可迭代对象的第一个元素就作为appFun的第一个元素,而可迭代器的从第二个元素到最后依次作为appFun的第二个参数,除第一次调用之外,appFun的第一个参数就是appFun的返回值了。例如reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]),计算1到5的和,因为没有给定initializer参数,所以第一次调用x+y时,x=1,即列表的第一个元素,y=2,即列表的第二个元素,之后返回的1+2的结果作为第二次调用x+y中的x,即上一次的结果,y=2,即第二个元素,依次类推,知道得到1+2+3+4+5的结果。

这样看来,其实下面的代码定义是有一点问题,我们在程序中调用这段代码reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]),得到的结果为16,而正确的结果为15,问题在于如果集合不是以0开始,那么按照如下代码,第一次调用x=1,即第一个元素,y也是等于1,也是第一个元素,而正确的y应该是2。所以真正的reduce方法应该和下面的例子是有差别的。

def reduce(function, iterable, initializer=None): 
  it = iter(iterable) 
  if initializer is None: 
    try: 
      initializer = next(it) 
    except StopIteration: 
      raise TypeError('reduce() of empty sequence with no initial value') 
  accum_value = initializer 
  for x in iterable: 
    accum_value = function(accum_value, x) 
  return accum_value

那么reduce函数能做什么,什么情况下要用reduce呢,看下面的例子:

例如上面的例子,实现一个整形集合的累加。假设lst = [1,2,3,4,5],实现累加的方式有很多:

第一种:用sum函数

sum(lst)

 
第二种:循环方式。

def customer_sum(lst): 
  result = 0 
  for x in lst: 
    result+=x 
  return result 
 
#或者 
def customer_sum(lst): 
  result = 0 
  while lst: 
      temp = lst.pop(0) 
      result+=temp 
  return result 
 
if __name__=="__main__": 
  lst = [1,2,3,4,5] 
  print customer_sum(lst)

第三种:递推求和

def add(lst,result): 
  if lst: 
    temp = lst.pop(0) 
    temp+=result 
    return add(lst,temp) 
  else: 
    return result 
 
if __name__=="__main__": 
  lst = [1,2,3,4,5] 
  print add(lst,0)

第四种:reduce方式

lst = [1,2,3,4,5] 
print reduce(lambda x,y:x+y,lst) 
#这种方式用lambda表示当做参数,因为没有提供reduce的第三个参数,所以第一次执行时x=1,y=2,第二次x=1+2,y=3,即列表的第三个元素 
 
 
#或者 
lst = [1,2,3,4,5] 
print reduce(lambda x,y:x+y,lst,0) 
#这种方式用lambda表示当做参数,因为指定了reduce的第三个参数为0,所以第一次执行时x=0,y=1,第二次x=0+1,y=2,即列表的第二个元素, 
假定指定reduce的第三个参数为100,那么第一次执行x=100,y仍然是遍历列表的元素,最后得到的结果为115 
 
 
 
#或者 
def add(x,y): 
  return x+y 
 
print reduce(add, lst) 
#与方式1相同,只不过把lambda表达式换成了自定义函数 
 
#或者 
def add(x,y): 
  return x+y 
 
print reduce(add, lst,0) 
#与方式2相同,只不过把lambda表达式换成了自定义函数

 
再举一个例子:有一个序列集合,例如[1,1,2,3,2,3,3,5,6,7,7,6,5,5,5],统计这个集合所有键的重复个数,例如1出现了两次,2出现了两次等。大致的思路就是用字典存储,元素就是字典的key,出现的次数就是字典的value。方法依然很多

第一种:for循环判断

def statistics(lst): 
  dic = {} 
  for k in lst: 
    if not k in dic: 
      dic[k] = 1 
    else: 
      dic[k] +=1 
  return dic 
 
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5] 
print(statistics(lst))

第二种:比较取巧的,先把列表用set方式去重,然后用列表的count方法

def statistics2(lst): 
  m = set(lst) 
  dic = {} 
  for x in m: 
    dic[x] = lst.count(x) 
 
  return dic 
 
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5] 
print statistics2(lst)

第三种:用reduce方式

def statistics(dic,k): 
  if not k in dic: 
    dic[k] = 1 
  else: 
    dic[k] +=1 
  return dic 
 
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5] 
print reduce(statistics,lst,{})  
#提供第三个参数,第一次,初始字典为空,作为statistics的第一个参数,然后遍历lst,作为第二个参数,然后将返回的字典集合作为下一次的第一个参数 
 
或者 
d = {} 
d.extend(lst) 
print reduce(statistics,d) 
#不提供第三个参数,但是要在保证集合的第一个元素是一个字典对象,作为statistics的第一个参数,遍历集合依次作为第二个参数

通过上面的例子发现,凡是要对一个集合进行操作的,并且要有一个统计结果的,能够用循环或者递归方式解决的问题,一般情况下都可以用reduce方式实现。

reduce函数真是“一位好同志啊”!

Python 相关文章推荐
python实现zencart产品数据导入到magento(python导入数据)
Apr 03 Python
python实现的解析crontab配置文件代码
Jun 30 Python
python对url格式解析的方法
May 13 Python
python实现数组插入新元素的方法
May 22 Python
基于Python socket的端口扫描程序实例代码
Feb 09 Python
pytest中文文档之编写断言
Sep 12 Python
Python 矩阵转置的几种方法小结
Dec 02 Python
Python2和Python3中@abstractmethod使用方法
Feb 04 Python
pytorch:model.train和model.eval用法及区别详解
Feb 20 Python
python实现手势识别的示例(入门)
Apr 15 Python
django注册用邮箱发送验证码的实现
Apr 18 Python
python单元测试之pytest的使用
Jun 07 Python
Python中使用ConfigParser解析ini配置文件实例
Aug 30 #Python
python进阶教程之动态类型详解
Aug 30 #Python
python进阶教程之异常处理
Aug 30 #Python
python进阶教程之函数对象(函数也是对象)
Aug 30 #Python
python进阶教程之循环对象
Aug 30 #Python
python进阶教程之循环相关函数range、enumerate、zip
Aug 30 #Python
python进阶教程之函数参数的多种传递方法
Aug 30 #Python
You might like
用PHP制作静态网站的模板框架(二)
2006/10/09 PHP
利用Ffmpeg获得flv视频缩略图和视频时间的代码
2011/09/15 PHP
PHP二维数组排序的3种方法和自定义函数分享
2014/04/09 PHP
PHP获取远程图片并保存到本地的方法
2015/05/12 PHP
php常用表单验证类用法实例
2015/06/18 PHP
PHP的文件操作与算法实现的面试题示例
2015/08/10 PHP
PHP递归实现层级树状展开
2016/04/01 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
php5.x禁用eval的操作方法
2018/10/19 PHP
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
2011/04/12 Javascript
在JavaScript中处理字符串之link()方法的使用
2015/06/08 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
在JavaScript中调用Java类和接口的方法
2016/09/07 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
2017/01/05 Javascript
jQuery插件echarts实现的循环生成图效果示例【附demo源码下载】
2017/03/04 Javascript
webpack 2.x配置reactjs基本开发环境详解
2017/08/08 Javascript
基于jQuery的表单填充实例
2017/08/22 jQuery
vue input输入框关键字筛选检索列表数据展示
2020/10/26 Javascript
angular异步验证防抖踩坑实录
2019/12/01 Javascript
《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析
2020/04/08 Javascript
python一键去抖音视频水印工具
2018/09/14 Python
Python中Numpy mat的使用详解
2019/05/24 Python
Python使用__new__()方法为对象分配内存及返回对象的引用示例
2019/09/20 Python
Python 异步协程函数原理及实例详解
2019/11/13 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
PyPDF2读取PDF文件内容保存到本地TXT实例
2020/05/12 Python
Python爬虫实现自动登录、签到功能的代码
2020/08/20 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
HTML5 transform三维立方体实现360无死角三维旋转效果
2014/08/22 HTML / CSS
英国山地公路自行车商店:Tweeks Cycles
2018/03/16 全球购物
Charles&Keith美国官方网站:新加坡快时尚鞋类和配饰零售商
2019/11/27 全球购物
英语专业毕业生自荐信范文
2013/12/31 职场文书
大学英语演讲稿(中英文对照)
2014/01/14 职场文书
情况说明书格式范文
2014/05/06 职场文书
2016年中秋节慰问信
2015/12/01 职场文书