在介绍函数式编程之前,先介绍几个概念性的东西。

什么是函数式编程?

函数式编程的特点:

1.把计算视为函数而非指令;

2.纯函数式编程:不需要变量,没有副作用,测试简单;

3.支持高阶函数,代码简洁。

什么是高阶函数?

能接收函数做参数的函数,称为高阶函数。

高阶函数的特点:

1.变量可以指向函数

2.函数的参数可以接收变量

3.一个函数可以接收另一个函数作为参数

Python支持的函数式编程?

1.不是纯函数式编程:允许有变量

2.支持高阶函数:函数也可以作为变量传入

3.支持闭包:有了闭包就能返回函数

4.有限度的支持匿名函数

关于匿名函数和闭包的介绍,后面会一一介绍,暂时不在这里详细介绍。

高阶函数-把函数作为参数

>>> def fn(x,y,f):
... return f(x)+f(y)
...
>>> import math
>>> fn(4,16,math.sqrt)
6.0

python内置的几个常用的高阶函数

map():接收一个函数f和一个list对象,函数f作用于list对象的每一个元素,并返回一个新的list对象。

>>> def fn(x):
... return x*x;
...
>>> print map(fn,range(1,11))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

reduce():也是接收函数f和一个list对象,但是接收函数f必须传入两个参数,然后对lsit中的每一个元素反复调用函数f,并返回最终结果值。

>>> def prod(x,y):
... return x*y
...
>>> print reduce(prod,range(1,6))
120 //1 *2*3*4*5

filter():接收函数f和一个list对象,函数f的作用是对每一个list对象的元素进行判断,返回true 和false。filter()根据判断结果自动过滤掉不符合的元素,返回符合条件的元素组成的新list。

>>> def is_even_number(x):
... return x%2==0
...
>>> filter(is_even_number,range(1,11))
[2, 4, 6, 8, 10]

上面针对高阶函数讲解,大家应该了解了函数是可以作为参数的,那么既然函数可以做参数,那么也可以返回函数。

返回函数

>>> def f():
... print 'call f()....'
... //定义函数g:
... def g():
... print 'call g()....'
//返回函数g:
... return g
...
>>> x = f() //调用f()
call f()....
>>> x
<function g at 0x7f62fab01c80>
>>> x() //调用x()就是执行g()函数定义的代码
call g()....

举个例子:编写一个函数,接收一个list,返回一个函数,返回函数可以计算参数的乘积。

>>> def fn(x,y):
... return x*y;
...
>>> def calc_prod(lst):
... def my_calc():
... return reduce(fn,lst)
... return my_calc
...
>>> f = calc_prod(range(1,5))
>>> print f()
24

闭包

内层函数引用外层函数的变量,然后返回内层函数的情况,称为闭包。

闭包的特点:返回的函数引用了外层函数的局部变量。所以,要正确使用闭包,就能确保引用的局部变量在函数返回后不能改变。举例说明:

//希望一次返回3个函数,分别计算1x1,2x2,3x3
>>> def count():
... lst = []
... for i in range(1,4):
... def f():
... return i*i
... lst.append(f)
... return lst
...
>>> f1,f2,f3 = count()
>>> f1()
9
>>> f2()
9
>>> f3()
9

得到的结果并不是我们预期的1,4,9.

lst.append(f),只是将每一个f()的引用保存进了list,并没有进行对于i的计算,所以导致最后在运行了f(1)之后,i已经变为了3.

因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量

那么怎么改写上述的代码,得到想要的1,4,9.值。

方法一:

>>> def count():
... lst = []
... for i in range(1,4):
... def f():
... return i*i
... lst.append(f()) //很大的不同,f 变为了f(),这一步的时候已经进行了i*i的运算
... return lst
...
>>> f1,f2,f3 = count()
>>> print f1,f2,f3
1 4 9

方法二:

>>> def count():
... lst = []
... for i in range(1,4):
... def f(m=i)://传入参数
... return m*m
... lst.append(f)
... return lst
...
>>> f1,f2,f3 = count()
>>> print f1(),f2(),f3()
1 4 9

问题的产生是因为函数只在执行时才去获取外层参数i,若函数定义时可以获取到i,问题便可解决。而默认参数正好可以完成定义时获取i值且运行函数时无需参数输入的功能,所以在函数f()定义中改为f(m = i),函数f返回值改为m*m即可.

匿名函数

关键字 lambda表示匿名函数,冒号前面的x表示函数参数。

匿名函数有个限制,就是只能有一个表达式,不能写return,返回值就直接写表达式的结果。

例子一:

>>> map(lambda x:x*x,range(1,5))
[1, 4, 9, 16]

lambda x:x*x,可以看做是

>>> def f(x):
... return x*x

例子二:

>>> myabs = lambda x:-x if x<0 else x
>>> myabs(-1)
1
>>> myabs(2)
2

lambda x:-x if x<0 else x可以看做是

>>> def f(x):
... x = -x
... if x<0:
... return -x
... else:
... return x

小结:这一节主要讲解python函数式编程概念及其python高阶函数的定义及其使用。

python学习第十一天 -- 函数式编程的更多相关文章

  1. Python学习总结之五 -- 入门函数式编程

    函数式编程 最近对Python的学习有些怠慢,最近的学习态度和学习效率确实很不好,目前这种病况正在好转. 今天,我把之前学过的Python中函数式编程简单总结一下,分享给大家,也欢迎并感谢大家提出意见 ...

  2. Python学习笔记二:函数式编程

    1:Python中,内置函数名相当于一个变量,指向内置函数.所以可以通过函数名调用相应函数,也可以给函数名赋值,改变它的内容,如:可以把另一个函数变量赋值给它,那它就指向了所赋值的函数了. 2:高级函 ...

  3. Python学习札记(二十) 函数式编程1 介绍 高阶函数介绍

    参考: 函数式编程 高阶函数 Note A.函数式编程(Functional Programming)介绍 1.函数是Python内建支持的一种封装,我们通过一层一层的函数调用把复杂任务分解成简单的任 ...

  4. Python学习一(面向对象和函数式编程)

    学习了一周的Python,虽然一本书还没看完但是也收获颇多,作为一个老码农竟然想起了曾经荒废好久的园子,写点东西当做是学习笔记吧 对Python的语法看的七七八八了,比较让我关注的还是他编程的思想,那 ...

  5. Python学习札记(二十三) 函数式编程4 sorted

    参考:sorted NOTE 1.sorted,快速排序,时间复杂度O(nlogn)渐进最优. #!/usr/bin/env python3 L = [] for i in range(10): L. ...

  6. Python学习札记(二十七) 函数式编程8 偏函数

    偏函数 NOTE 1.int()函数提供额外的base参数,默认值为10.如果传入base参数,就可以做N进制的转换: #!/usr/bin/env python3 import functools ...

  7. python学习,day3:函数式编程,递归和高阶函数

    # coding=utf-8 # Author: RyAn Bi def calc(n): #递归 print(n) if int(n/2) > 0: #设置条件,否则会循环999 次,报错, ...

  8. python学习,day3:函数式编程,局部变量和全局变量

    # coding=utf-8 # Author: RyAn Bi school = 'THU' #全局变量 def change_name(name): global age #在函数中,用globa ...

  9. python学习,day3:函数式编程,*arge,**kwargs

    对于不固定长度的参数,需要使用*arge,**kwargs来调用,区别是*arge是转换为元组,而kwargs转化为字典 # coding=utf-8 # Author: RyAn Bi def te ...

随机推荐

  1. Largest product in a series

    这个我开始理解错了,算错了. 我以为是求连续5个数的最大值,结果,是连接5个数相乘的最大值. 英语不好,容易吃亏啊. Find the greatest product of five consecu ...

  2. Android中的手势

    Android对两种手势行为提供了支持:1.对于第一种手势行为而言,Android提供了手势检测,并为手势检测提供了相应的监听器.2.对于第二种手势行为,Android允许开发者添加手势,并提供了相应 ...

  3. C51系列RAM寄存器表

    特殊功能寄存器地址表 SFR 符号 字节 地址 位地址和位名称 D7 D6 D5 D4 D3 D2 D1 D0 P0口 P0 80H P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0. ...

  4. 杜教的AAA树

    膜膜膜,常数挺小的... #include<iostream> #include<cstdio> #include<cmath> #include<algor ...

  5. Android调用系统相机和文件浏览器

    //拍照功能,调用系统的相机功能 Intent intent2 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResul ...

  6. HDU_1426——数独问题,DFS

    Problem Description 自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会将数独列为一个单独的项目进行 ...

  7. windows server2012域服务器降级的方法

    最近在一个新的网络环境里建立windows域服务器,准备建立主.备两台域服务器.在一台新服务器上面安装了windows2012R2并配置了DC服务.域和林的级别设置为Windows2012R2级别.在 ...

  8. Java编程思想-第四章练习题

    练习1:写一个程序,打印从1到100的值 public class Print1To100{ public static void main(String args[]){ for(int i = 1 ...

  9. jTemplates——学习(1)

    这里介绍一个基于jQuery开发的模板引擎. jTemplates目前最新的版本是0.7.8,由tPython开发.官方网站:http://jtemplates.tpython.com 两个附件, 一 ...

  10. (转)awk命令

    转自:http://man.lupaworld.com/content/manage/ringkee/awk.htm#id2874788 整理:Jims of 肥肥世家 <jims.yang@g ...