python基础-函数_递归_ 匿名函数_高阶函数_lambda_map函数_filter函数_reduce函数

一、数学定义的函数与python中的函数

  初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域

例如y=2*x

 

python中函数定义:函数是逻辑结构化和过程化的一种编程方法。

 1 python中函数定义方法:
 2  
 3 def test(x):
 4     "The function definitions"
 5     x+=1
 6     return x
 7      
 8 def:定义函数的关键字
 9 test:函数名
10 ():内可定义形参
11 "":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
12 x+=1:泛指代码块或程序处理逻辑
13 return:定义返回值
14 
15 
16 调用运行:可以带参数也可以不带
17 函数名()

 

 ps1: 直接定义参数,返回的就是内存地址

1 def test(x):   #直接定义参数,返回的就是内存地址
2     y=2*x+1
3     return y
4 print(test)

执行结果:

1 <function test at 0x01792F60>  #返回内存地址

 

ps2:直接定义参数,反面就要给参数,否则报错

1 def test(x):    #直接定义参数,后面就要给参数,否则报错
2     y=2*x+1
3     return y
4 print(test)
5 
6 a=test(3)    #这里必须给参数,不给就报错
7 print(a)

执行结果:

1 <function test at 0x013C2F60>
2 7   #计算结果是:7

 

ps3:  没有直接定义参数,在函数中定义参数

 1 def test():   #这里没有直接定义参数,在函数定义参数
 2     '''
 3     2*x+1
 4     :param x:整形数字
 5     :return: 返回计算结果
 6     '''
 7     x=3       #定义参数
 8     y=2*x+1
 9     return y
10 a=test()
11 print(a)

执行结果:

1 7

补充:

1.编程语言中的函数与数学意义的函数是截然不同的俩个概念,编程语言中的函数是通过一个函数名封装好一串用来完成某一特定功能的逻辑,数学定义的函数就是一个等式,等式在传入因变量值x不同会得到一个结果y,这一点与编程语言中类似(也是传入一个参数,得到一个返回值),不同的是数学意义的函数,传入值相同,得到的结果必然相同且没有任何变量的修改(不修改状态),而编程语言中的函数传入的参数相同返回值可不一定相同且可以修改其他的全局变量值(因为一个函数a的执行可能依赖于另外一个函数b的结果,b可能得到不同结果,那即便是你给a传入相同的参数,那么a得到的结果也肯定不同)

2.函数式编程就是:先定义一个数学函数(数学建模),然后按照这个数学模型用编程语言去实现它。至于具体如何实现和这么做的好处,且看后续的函数式编程。

 

二 、为何使用函数

背景提要

  现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码

 1 while True:
 2     if cpu利用率 > 90%:
 3         #发送邮件提醒
 4         连接邮箱服务器
 5         发送邮件
 6         关闭连接
 7      
 8     if 硬盘使用空间 > 90%:
 9         #发送邮件提醒
10         连接邮箱服务器
11         发送邮件
12         关闭连接
13      
14     if 内存占用 > 80%:
15         #发送邮件提醒
16         连接邮箱服务器
17         发送邮件
18         关闭连接

上面的代码实现了功能,但即使是邻居老王也看出了端倪,老王亲切的摸了下你家儿子的脸蛋,说,你这个重复代码太多了,每次报警都要重写一段发邮件的代码,太low了,这样干存在2个问题:

  1. 代码重复过多,一个劲的copy and paste不符合高端程序员的气质

  2. 如果日后需要修改发邮件的这段代码,比如加入群发功能,那你就需要在所有用到这段代码的地方都修改一遍

      其实很简单,只需要把重复的代码提取出来,放在一个公共的地方,起个名字,以后谁想用这段代码,就通过这个名字调用就行了,如下:

 1 def 发送邮件(内容)
 2     #发送邮件提醒
 3     连接邮箱服务器
 4     发送邮件
 5     关闭连接
 6      
 7 while True:
 8      
 9     if cpu利用率 > 90%:
10         发送邮件('CPU报警')
11      
12     if 硬盘使用空间 > 90%:
13         发送邮件('硬盘报警')
14      
15     if 内存占用 > 80%:
16         发送邮件('内存报警')

总结使用函数的好处:

1.代码重用

2.保持一致性,易维护

3.可扩展性

 

三、函数和过程

过程定义:过程就是简单特殊没有返回值的函数

这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情

 1 def test01():
 2     msg='hello The little green frog'
 3     print msg
 4  
 5 def test02():
 6     msg='hello WuDaLang'
 7     print msg
 8     return msg
 9  
10  
11 t1=test01()
12  
13 t2=test02()
14  
15  
16 print 'from test01 return is [%s]' %t1
17 print 'from test02 return is [%s]' %t2

总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

所以在python中即便是过程也可以算作函数。

 1 def test01():
 2     pass
 3  
 4 def test02():
 5     return 0
 6  
 7 def test03():
 8     return 0,10,'hello',['alex','lb'],{'WuDaLang':'lb'}
 9  
10 t1=test01()
11 t2=test02()
12 t3=test03()
13  
14  
15 print 'from test01 return is [%s]: ' %type(t1),t1
16 print 'from test02 return is [%s]: ' %type(t2),t2
17 print 'from test03 return is [%s]: ' %type(t3),t3

 

ps1:

 1 #过程:就是没有返回值的函数
 2 
 3 def test01():
 4     msg = 'test01'
 5     print(msg)
 6 
 7 def test02():
 8     msg = 'test02'
 9     print(msg)
10     return msg
11 
12 def test03():
13     msg = 'test03'
14     print(msg)
15     return 1,2,3,4,'a',['alex'],{'name':'alex'},None
16 
17 def test04():
18     msg = 'test03'
19     print(msg)
20     return {'name':'alex'}
21 t1=test01()
22 t2=test02()
23 t3=test03()
24 t4=test04()
25 print(t1)
26 print(t2)
27 print(t3)
28 print(t4) 

执行结果:

1 test01
2 test02
3 test03
4 test03
5 None
6 test02
7 (1, 2, 3, 4, 'a', ['alex'], {'name': 'alex'}, None)
8 {'name': 'alex'}   #得到的值就是字典

 

 

总结:

   返回值数=0:返回None

   返回值数=1:返回object

   返回值数>1:返回tuple

 

四、函数参数

1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)

ps1:

 

1 def calc(x,y):  #x=2,y=3
2     res=x**y
3     return x    #函数一遇到return就结束掉
4     return y    #可以写多个,但没有意义
5 res=calc(2,3)
6 print(res)

执行结果:

1 2

 

ps2:  位置参数,必须一一对应,缺一不行多一也不行

1 def test(x,y,z):  #x=1,y=2,z=3
2     print(x)
3     print(y)
4     print(z)
5 test(1,2,3)

执行结果:

1 1
2 2
3 3

 

ps3: 关键字参数,无须一一对应,缺一不行多一也不行

1 def test(x,y,z):  #x=1,y=2,z=3
2     print(x)
3     print(y)
4     print(z)
5 test(y=1,x=3,z=4)

执行结果:

1 3
2 1
3 4

 

ps4: 位置参数必须在关键字参数左边

1 def test(x,y,z):  #x=1,y=2,z=3
2     print(x)
3     print(y)
4     print(z)
5 # test(1,y=2,3)#报错
6 # test(1,3,y=2)#报错
7 test(1,3,z=2)
8 # test(1,3,z=2,y=4)#报错
9 # test(z=2,1,3)#报错

执行结果:

1 1
2 3
3 2

 

ps5:

1 def handle(x,type='mysql'):
2     print(x)
3     print(type)
4 # handle('hello')
5 # handle('hello',type='sqlite')
6 handle('hello','sqlite')
# def install(func1=False,func2=True,func3=True):
# pass

执行结果:

1 hello
2 sqlite

 

4.默认参数

5.参数组

参数组:**字典 *列表

 

*列表方法介绍

 ps1:

1 def test(x,*args):
2     print(x)
3     print(args)
4 
5 test(1)

执行结果:

1 1
2 ()

 

ps2:

1 def test(x,*args):
2     print(x)
3     print(args)
4 
5 test(1,2,3,4,5)

执行结果:

1 1
2 (2, 3, 4, 5)

 

ps3:

1 def test(x,*args):
2     print(x)
3     print(args)
4 test(1,{'name':'alex'})  #传字典

执行结果:

1 1
2 ({'name': 'alex'},)

 

ps4:

1 def test(x,*args):
2     print(x)
3     print(args)
4 test(1,['x','y','z']) #当成一个值,放到元组中

执行结果:

1 1
2 (['x', 'y', 'z'],)

 

ps5:

1 def test(x,*args):
2     print(x)
3     print(args)
4 test(1,*['x','y','z'])   #加* 传列表类型

执行结果:

1 1
2 ('x', 'y', 'z')

 

ps6:

1 def test(x,*args):
2     print(x)
3     print(args)
4 
5 test(1,*('x','y','z'))   #传元组

执行结果:

1 1
2 ('x', 'y', 'z')

 

**字典的方法介绍

ps1:

1 def test(x,**kwargs):    #最好写**kwargs ,写成其它**Xxxx也可以。但最好写**Kwargs
2     print(x)
3     print(kwargs)
4 
5 # test(1,y=2,z=3)
6 #test(1,1,2,2,2,2,2,y=2,z=3)   #会报错:位置参数,必须一一对应
7 # test(1,y=2,z=3,z=3)          #会报错:一个参数不能传两个值

执行结果:

1 1
2 {'z': 3, 'y': 2}

 

ps2:

1 def test(x,*args,**kwargs):
2     print(x)
3     print(args,args[-1])
4     print(kwargs,kwargs.get('y'))
5 # test(1,1,2,1,1,11,1,x=1,y=2,z=3) #得到多个值,会报错,不能这么用。
6 test(1,1,2,1,1,11,1,y=2,z=3)

执行结果:

1 1
2 (1, 2, 1, 1, 11, 1) 1
3 {'z': 3, 'y': 2} 2

 

ps3:

1 def test(x,*args,**kwargs):
2     print(x)
3     print(args,args[-1])
4     print(kwargs,kwargs.get('y'))   #获得字典,用get的方法
5 
6 test(1,*[1,2,3],**{'y':1})

执行结果:

1 1
2 (1, 2, 3) 3
3 {'y': 1} 1

 

五、局部变量与全局变量

1.什么是全局变量

  在globals中的变量,都是全局变量,全局变量的作用域就是整个程序

2.什么是局部变量

  顾名思义就是只能在局部可以执行的变量,在子程序中定义的变量就称为局部变量,局部变量的作用域是定义该变量的子程序。

3.当全局变量与局部变量同名时:

  在定义局部变量的子程序中,局部变量生效,在其他地方全局变量生效。

4.定义全局变量和局部变量的命名规法

      1、全局变量变量名必须大写

      2、局部变量变量名必须小写

      3、全局变量必须写在局部变量的上面,并且顶格写。

 

ps1:

1 name= 'lhf'
2 
3 def change_name():
4     print('我的名字',name)
5 
6 change_name()

执行结果:

1 我的名字 lhf

 

ps2:

1 name= 'lhf'
2 def change_name():
3     name='帅了一笔'
4     print('我的名字',name)   #局部变量直接从里层开始读
5 
6 change_name()
7 print(name)

执行结果:

1 我的名字 帅了一笔
2 lhf

 

ps3:

1 name= 'lhf'
2 def change_name():
3     global name      #global全局变量,从最外层开始读,再读里层
4     name='帅了一笔'
5     print('我的名字',name)
6 
7 change_name()
8 print(name)

执行结果:

1 我的名字 帅了一笔
2 帅了一笔

 

ps4:

 1 NAME = "杠娘"
 2 
 3 def yangjian():
 4     # NAME = "史正文"
 5     global NAME
 6     NAME = "小东北"
 7     print('我要搞', NAME)
 8 
 9 def qupengfei():
10     # NAME = "基"
11     print('我要搞', NAME)
12 
13 yangjian()
14 qupengfei()

执行结果:

1 我要搞 小东北
2 我要搞 小东北

 

ps5: global声明全局变量,就从最上面开始往下一层一层读取

 1 NAME = "产品经理"
 2 
 3 def yangjian():
 4     # NAME = "史正文"
 5     global NAME # 已经声明,NAME就是全局的的那个变量
 6     print('我要搞', NAME)
 7     NAME = "小东北"  # 修改 全局的变量
 8     print('我要搞', NAME)
 9 
10 def qupengfei():
11     NAME = ""
12     print('我要搞', NAME)

执行结果:

1 刚娘
2 冷静
3 刚娘

 

ps6: nolocal 指定上一级变量,如果没有就继续往上,一直找到为止。

 1 name = "刚娘"
 2 
 3 def weihou():
 4     name = "陈卓"
 5     def weiweihou():
 6         nonlocal name   # nonlocal,指定上一级变量,如果没有就继续往上一直到找到为止
 7         name = "冷静"
 8     weiweihou()
 9     print(name)
10 print(name)
11 
12 weihou()
13 print(name)

执行结果:

1 刚娘
2 冷静
3 刚娘

全局变量和局部变量有无global关键字的区别

一、 如果函数的内容无global关键字

 1、有声明局部变量

1 NAME = ["产品经理","廖波诗"]
2 def qupengfei():
3     NAME = "自己"
4     print('我要搞',NAME)
5 qupengfei()

执行结果:

1 我要搞 自己

 

2、无声明局部变量

1 NAME = ["产品经理","廖波诗"]
2 def qupengfei():
3     NAME.append('XXOO')
4     print('我要搞',NAME)
5 qupengfei()

执行结果:

1 我要搞 ['产品经理', '廖波诗', 'XXOO']

 

 二、如果函数的内容有global关键字

1、有声明局部变量

1 NAME = ["产品经理","廖波诗"]
2 def qupengfei():
3     NAME = "自己"
4     print('我要搞',NAME)
5 qupengfei()

执行结果:

1 我要搞 自己

 

2、无声明局部变量

1 NAME = ["产品经理","廖波诗"]
2 def qupengfei():
3     global NAME
4     NAME = ["阿毛"]
5     NAME.append('XXOO')
6     print('我要搞',NAME)
7 qupengfei()

执行结果:

1 我要搞 ['阿毛', 'XXOO']

 

全局变量和局部变量的总结:

1、优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME=“fff”,

2、但是对于可变类型,可以对内部元素进行操作

3、如果函数中有global关键字,变量本质上就是全局的那个变量,可读取可赋值 NAME=“fff”

ps1:

 1 NAME = ["产品经理","廖波湿"]
 2 
 3 def yangjian():
 4     # NAME = "史正文"
 5     global NAME # 已经声明,NAME就是全局的的那个变量
 6     print('我要搞', NAME)
 7     NAME = "小东北"  # 修改 全局的变量
 8     print('我要搞', NAME)
 9 
10 def qupengfei():
11     # NAME = "aS"
12     NAME.append('天扎龙')
13     print('我要搞', NAME)
14 
15 qupengfei()

执行结果:

1 我要搞 小东北
2 我要搞 小东北
3 我要搞 ['产品经理', '廖波湿', '天扎龙']

 函数可以多层嵌套

ps1:

 1 name = '刚娘'
 2 
 3 def weihou():
 4     name = "陈卓"
 5     def weiweihou():
 6         global name
 7         name = '冷静'
 8     weiweihou()
 9     print(name)
10 
11 print(name)
12 weihou()
13 print(name)

执行结果:

1 刚娘
2 陈卓
3 冷静

 

ps2:

 1 NAME = '海风'
 2 
 3 def huangwei():
 4     name = "黄伟"
 5     print(name)
 6     def liuyang():
 7         name = "刘洋"
 8         print(name)
 9         def nulige():
10             name = '运维哥'
11             print(name)
12     liuyang()
13     print(name)
14 
15 huangwei()

执行结果:

1 黄伟
2 刘洋
3 黄伟

 

六、前向引用之'函数即变量'

 

原理图:

 

ps1: 错误的引用方法

1 def foo():
2     print('from foo')
3     bar()
4 
5 foo()

执行结果:

1 from foo
2   File "D:/python/day6/Forward reference.py", line 7, in <module>
3     foo()
4   File "D:/python/day6/Forward reference.py", line 5, in foo
5     bar()
6 NameError: name 'bar' is not defined

 

ps2:

1 def foo():
2     print('from foo')
3     bar()
4 
5 foo()
6 
7 def bar():
8     print('from bar')

执行结果:

1 Traceback (most recent call last):
2 from foo
3   File "D:/python/day6/Forward reference.py", line 31, in <module>
4     foo()
5   File "D:/python/day6/Forward reference.py", line 29, in foo
6     bar()
7 NameError: name 'bar' is not defined

 

ps3: 正在的引用方法

1 def bar():
2     print('from bar')
3 def foo():
4     print('from foo')
5     bar()
6 
7 foo()

执行结果:

1 from foo
2 from bar

 

ps4:正确的引用方法

1 def foo():
2     print('from foo')
3     bar()
4 
5 def bar():
6     print('from bar')
7 foo()

执行结果:

1 from foo
2 from bar

 

七、嵌套函数

看上面的标题的意思是,函数还能套函数?of course

 1 name = "Alex"
 2  
 3 def change_name():
 4     name = "Alex2"
 5  
 6     def change_name2():
 7         name = "Alex3"
 8         print("第3层打印",name)
 9  
10     change_name2() #调用内层函数
11     print("第2层打印",name)
12  
13  
14 change_name()
15 print("最外层打印",name)

此时,在最外层调用change_name2()会出现什么效果?

没错, 出错了, 为什么呢?

 

 八、递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

 ps1:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author: nulige
 4 
 5 import time
 6 
 7 def calc(n):
 8     print(n)
 9     if int(n / 2) == 0:
10         return n
11     time.sleep(3)   #等待3秒,再打印值
12     res=calc(int(n / 2))
13     return res
14 
15 calc(10)

执行结果:

1 10
2 5
3 2
4 1

讲解原理图:

ps2: 递归问路示例

 1 import time
 2 
 3 person_list=['alex','wupeiqi','yuanhao','linhaifeng']
 4 def ask_way(person_list):
 5     print('-'*60)
 6     if len(person_list) == 0:
 7         return '没人知道'
 8     person=person_list.pop(0)
 9     if person == 'linhaifeng':
10         return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
11     print('hi 美男[%s],敢问路在何方' %person)
12     print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' %(person,person_list))
13     time.sleep(3)
14     res=ask_way(person_list)
15     # print('%s问的结果是: %res' %(person,res))
16     return res
17 
18 
19 
20 res=ask_way(person_list)
21 
22 print(res)

执行结果:

 1 ------------------------------------------------------------
 2 hi 美男[alex],敢问路在何方
 3 alex回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['wupeiqi', 'yuanhao', 'linhaifeng']...
 4 ------------------------------------------------------------
 5 hi 美男[wupeiqi],敢问路在何方
 6 wupeiqi回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['yuanhao', 'linhaifeng']...
 7 ------------------------------------------------------------
 8 hi 美男[yuanhao],敢问路在何方
 9 yuanhao回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问['linhaifeng']...
10 ------------------------------------------------------------
11 linhaifeng说:我知道,老男孩就在沙河汇德商厦,下地铁就是   #拿到结果返回值

讲解原理图:

 

递归特性:

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

 


 补充点其它知识:

1、引用时间模块,打印一个分隔箭头

1 import time
2 res=time.sleep(3)    #3秒打印一个分隔箭头
3 print('----------->')

执行结果:

1 ----------->

 九、 匿名函数

匿名函数就是不需要显示的指定函数

ps1:

1 def test1():
2     print('in the test1')
3 def test():
4     print('in the test')
5     return test1
6 
7 # print(test)
8 res=test()
9 print(res())  #test1()

执行结果:

1 in the test
2 in the test1
3 None

 

ps2:

 1 name='alex'
 2 
 3 def foo():
 4     name='lhf'
 5     def bar():
 6         print(name)
 7     return bar
 8 
 9 func=foo()
10 func()

执行结果:

1 lhf

 

ps3:

 1 name='alex'
 2 
 3 def foo():
 4     name='lhf'
 5     def bar():
 6         name='wupeiqi'
 7         def tt():
 8             print(name)
 9         return tt
10     return bar
11 
12 func=foo()
13 func()()

执行结果:

1 wupeiqi

 

匿名函数主要是和其它函数搭配使用

ps1:

 1 res = map(lambda x:x**2,[1,5,7,4,8])
 2 for i in res:
 3     print(i)
 4 
 5 输出
 6 1
 7 25
 8 49
 9 16
10 64

 

ps2: 实现字符串拼接

 1 #实现字符串拼接
 2 name='alex' #name='alex_sb'
 3 def change_name(x):
 4     return name+'_sb'
 5 
 6 res=change_name(name)
 7 print(res)
 8 
 9 #实现字符串拼接
10 func=lambda x:x+'_sb'
11 res=func(name)
12 print('匿名函数的运行结果',res)

执行结果:

1 alex_sb
2 匿名函数的运行结果 alex_sb

 

ps3:

1 func=lambda x,y,z:x+y+z
2 print(func(1,2,3))

执行结果:

6

 

十、函数式编程

http://egon09.blog.51cto.com/9161406/1842475

 

十一、 高阶函数

满足俩个特性任意一个即为高阶函数

1.函数的传入参数是一个函数名

2.函数的返回值是一个函数名

 

map函数  

作用:遍历序列,对序列中每个元素进行操作,最终获取新的序列

 

示例说明:循行渐进式演示引出map来

ps1:

1 num_l=[1,2,10,5,3,7]
2 num1_l=[1,2,10,5,3,7]
3 
4 ret=[]
5 for i in num_l:
6     ret.append(i**2)  #求平方
7 8 print(ret)

执行结果:

1 [1, 4, 100, 25, 9, 49]

 

ps2:

 1 num_l=[1,2,10,5,3,7]
 2 num1_l=[1,2,10,5,3,7]
 3 def map_test(array):
 4     ret=[]
 5     for i in num_l:
 6         ret.append(i**2)  #求平方
 7     return ret
 8 
 9 ret=map_test(num_l)
10 rett=map_test(num1_l)
11 print(ret)
12 print(rett)

执行结果:

1 [1, 4, 100, 25, 9, 49]
2 [1, 4, 100, 25, 9, 49]

 

ps3:

 1 #实现加、减、求平方
 2 num_1=[1,2,10,5,3,7]
 3 def add_one(x):
 4     return x+1     #每个元素加一
 5 
 6 def reduce_one(x):
 7     return x-1     #每个元素减一
 8 
 9 def pf(x):
10     return x**2    #求平方
11 
12 def map_test(func,array):
13     ret=[]
14     for i in num_1:
15         res=func(i)  #add_one(i)
16         ret.append(res)   #把值加到空列表中
17     return ret
18 
19 print(map_test(add_one,num_1))
20 print(map_test(reduce_one,num_1))
21 print(map_test(pf,num_1))

执行结果:

1 [2, 3, 11, 6, 4, 8]
2 [0, 1, 9, 4, 2, 6]
3 [1, 4, 100, 25, 9, 49]

 

ps4:

 1 #实现加、减、求平方
 2 num_l=[1,2,10,5,3,7]
 3 lambda x:x+1
 4 
 5 lambda x:x-1
 6 
 7 lambda x:x**2
 8 
 9 def map_test(func,array):
10     ret=[]
11     for i in num_l:
12         res=func(i) #add_one(i)
13         ret.append(res)
14     return ret
15 
16 print(map_test(lambda x:x+1,num_l))
17 print(map_test(lambda x:x-1,num_l))
18 print(map_test(lambda x:x**2,num_l))

执行结果:

1 [2, 3, 11, 6, 4, 8]
2 [0, 1, 9, 4, 2, 6]
3 [1, 4, 100, 25, 9, 49]

 

ps5: 最终版本

 1 #终极版本
 2 num_l=[1,2,10,5,3,7]
 3 
 4 def add_one(x):
 5     return x+1
 6 
 7 def reduce_one(x):
 8     return x-1
 9 
10 def pf(x):
11     return x**2
12 def map_test(func,array): #func=lambda x:x+1    arrary=[1,2,10,5,3,7]
13     ret=[]
14     for i in array:
15         res=func(i) #add_one(i)
16         ret.append(res)
17     return ret
18 
19 num_l=[1,2,10,5,3,7]
20 print(map_test(lambda x:x+1,num_l))
21 res=map(lambda x:x+1,num_l)
22 print('内置函数map,处理结果',res)
23 
24 # for i in res:
25 #     print(i)
26 print(list(res))
27 
28 print('传的是有名函数',list(map(reduce_one,num_l)))  #python3.x要用List, python2.x不用list

执行结果:

1 [2, 3, 11, 6, 4, 8]
2 内置函数map,处理结果 <map object at 0x0115AF30>
3 [2, 3, 11, 6, 4, 8]
4 传的是有名函数 [0, 1, 9, 4, 2, 6]

 

ps6: 用map+lambda+upper(把字母转成大写,加入到列表中)

1 msg='linhaifeng'   #全部转成大写,加入到列表中
2 print(list(map(lambda x:x.upper(),msg)))

执行结果:

1 ['L', 'I', 'N', 'H', 'A', 'I', 'F', 'E', 'N', 'G']

 

filter函数 

作用:对于序列中的元素进行筛选,最终获取到符合条件的序列

 

示例:循行渐进式演示引出filter来

ps1:  过滤掉sb开头的人,就加入到列表中

 1 movie_people=['sb_alex','sb_wupeiqi','linhaifeng','sb_yuanhao']
 2 
 3 def filter_test(array):
 4     ret=[]
 5     for p in array:
 6         if not p.startswith('sb'):  #过滤掉sb开头的人,就加入到列表中
 7                ret.append(p)
 8     return ret
 9 
10 res=filter_test(movie_people)
11 print(res)

执行结果:

1 ['linhaifeng']

 

ps2:

 1 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
 2 def sb_show(n):
 3     return n.endswith('sb')
 4 
 5 def filter_test(func,array):
 6     ret=[]
 7     for p in array:
 8         if not func(p):
 9                ret.append(p)
10     return ret
11 
12 res=filter_test(sb_show,movie_people)
13 print(res)

执行结果:

1 ['linhaifeng']

 

ps3:

 1 #终极版本
 2 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
 3 def sb_show(n):
 4     return n.endswith('sb')
 5 # #--->lambda n:n.endswith('sb')
 6 #
 7 def filter_test(func,array):
 8     ret=[]
 9     for p in array:
10         if not func(p):
11                ret.append(p)
12     return ret
13 
14 res=filter_test(lambda n:n.endswith('sb'),movie_people)
15 print(res)

执行结果:

1 ['linhaifeng']

 

ps4:

1 #filter函数
2 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
3 print(filter(lambda n:not n.endswith('sb'),movie_people))
4 
5 res=filter(lambda n:not n.endswith('sb'),movie_people)
6 print(list(res))
7 
8 print(list(filter(lambda n:not n.endswith('sb'),movie_people)))

执行结果:

1 <filter object at 0x01B7ACF0>
2 ['linhaifeng']
3 ['linhaifeng']

 

 reduce函数 

作用:对于序列内所有元素进行累计操作

 

示例:循行渐进式演示引出reduce来

ps1:

1 #求和
2 num_l=[1,2,3,100]
3 
4 res=0
5 for num in num_l:
6     res+=num
7 
8 print(res)

执行结果:

1 106

 

ps2:

1 #求和
2 num_l=[1,2,3,100]
3 def reduce_test(array):
4     res=0
5     for num in array:
6         res+=num
7     return res
8 
9 print(reduce_test(num_l))

执行结果:

1 106

 

ps3:

 1 #所有的值相乘
 2 num_l=[1,2,3,100]
 3 
 4 # def multi(x,y):
 5 #     return x*y
 6 # lambda x,y:x*y
 7 
 8 def reduce_test(func,array):
 9     res=array.pop(0)
10     for num in array:
11         res=func(res,num)
12     return res
13 
14 print(reduce_test(lambda x,y:x*y,num_l))

执行结果:

1 600

 

ps4:

 1 # 需求:100*1,100*2,100*3,100*100 传入一个参数:100
 2 num_l=[1,2,3,100]
 3 def reduce_test(func,array,init=None):
 4     if init is None:
 5         res=array.pop(0)
 6     else:
 7         res=init
 8     for num in array:
 9         res=func(res,num)
10     return res
11 
12 print(reduce_test(lambda x,y:x*y,num_l,100))

执行结果:

1 60000

 

ps5: 使用reduce函数

1 #reduce函数
2 #需求x+y=?
3 from functools import reduce   #使用这个函数,必须先引用一个模块
4 num_l=[1,2,3,100]
5 print(reduce(lambda x,y:x+y,num_l,1))  #指定默认参数1,得出结果:107
6 print(reduce(lambda x,y:x+y,num_l))    #不指定默认参数,得出结果:106

执行结果:

1 107
2 106

 

总结:

map:  处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样

filter: 遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来

ps1:

1 people=[
2     {'name':'alex','age':1000},
3     {'name':'wupei','age':10000},
4     {'name':'yuanhao','age':9000},
5     {'name':'linhaifeng','age':18},
6 ]
7 print(list(filter(lambda p:p['age']<=18,people)))

执行结果:

1 [{'age': 18, 'name': 'linhaifeng'}]

 

reduce: 处理一个序列,然后把序列进行合并操作

1 from functools import reduce  #先引入模块
2 print(reduce(lambda x,y:x+y,range(100),100))   #最后100表示是个初始值
3 print(reduce(lambda x,y:x+y,range(1,101)))

执行结果:

1 5050
2 5050
posted @ 2016-11-29 23:25  努力哥  阅读(478)  评论(0编辑  收藏  举报