lambda表达式
lambda表达式就是能嵌入到其他表达式当中的匿名函数(闭包)
意义:
2、引入了闭包。基本上常见的支持lambda表达式的语言里,不存在不支持闭包的lambda表达式;从函数式编程的角度来说,支持闭包也是很重要的。
创建语法:
lambda parameters:express
parameters:可选,如果提供,通常是逗号分隔的变量表达式形式,即位置参数。
expression:不能包含分支或循环(但允许条件表达式),也不能包含return(或yield)函数。如果为元组,则应用圆括号将其包含起来。
实例(实验环境为Python3.6)
两数求和:
#lambda >>>my_lambda = lambda x,y;x+y #执行 >>>result = my_lambda(1,2)
result=3
求n的阶乘:
>>>n=5 >>>reduce(lambda x,y:x*y, range(1,n+1) 120
把lambda 作为返回表达式
>>> b=lambda x:lambda y:x+y >>>a=b(3) >>>a(2) 5 >>>(b(2))(2) 4
内建函数:(map,reduce,filter,sorted)
map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回
(python3.6)
>>> list(map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])) [1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce()把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比如上面的求阶乘的代码。
字符串str也是一个序列,我们可以写一个吧str转换成int的函数:(python3.6)
>>> def char2num(s): ... return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] ... >>> from functools import reduce >>> reduce(lambda x,y:x*10+y,map(char2num,'13579')) 13579
filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
写一个从list[1,2,3,4,5,6]中删除偶数,保留奇数的程序(Python3.6)
>>> list(filter(lambda x:x%2==1,[1,2,3,4,5,6])) ... [1, 3, 5]
排序函数 sorted()和list.sort[]
python中,具体到对list进行排序的方法有俩,一个是list自带的sort方法,这个是直接对list进行操作,只有list才包含的方法;另外一个是内建函数sorted方法,可以对所有可迭代的对象进行排序操作,在本质上,list的排序和内建函数sorted的排序是差不多的,连参数都基本上是一样的
主要的区别在于,list的sort方法返回的是对已经存在的列表进行操作,而内建函数sorted方法返回的是一个新的list,而不是在原来的基础上进行的操作。
>>> help(sorted) Help on built-in function sorted in module builtins: sorted(iterable, key=None, reverse=False) Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order.
Python3中去除了cmp内置函数,同时sorted等函数也去除了cmp关键字,添加key关键字
使用sorted()方法和list.sort()方法进行排序 elements=[(2,12,"A"),(1,11,"N"),(1,3,"L"),(2,4,"B")] >>> sorted(elements) [(1, 3, 'L'), (1, 11, 'N'), (2, 4, 'B'), (2, 12, 'A')] 根据elements每个元组后两项进行排序,e表示列表中每个三元组元素 在表达式是元组,且lambda为一个函数的参数时,lambda表达式的圆括号是必需的 >>> elements.sort(key=lambda e:(e[1],e[2])) >>> elements [(1, 3, 'L'), (2, 4, 'B'), (1, 11, 'N'), (2, 12, 'A')] 分片方式得到同样的效果 >>> elements.sort(key=lambda e:e[1:3]) >>> elements [(1, 3, 'L'), (2, 4, 'B'), (1, 11, 'N'), (2, 12, 'A')] >>> elements.sort(key=lambda e:(e[2].lower(),e[1])) 以下两种方法等价,都可以通过调用area(5,3),结果相同 >>> area=lambda b,h:0.5*b*h >>> def area(b,h): return 0.5*b*h
闭包(简单介绍一下闭包)
在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包,举个栗子(以一个类似棋盘游戏的例子来说明。假设棋盘大小为50*50,左上角为坐标系原点(0,0),我需要一个函数,接收2个参数,分别为方向(direction),步长(step),该函数控制棋子的运动。 这里需要说明的是,每次运动的起点都是上次运动结束的终点。):
>>> origin=[0,0]
>>> def create(pos=origin):
... def go(direction,step):
... new_x=pos[0]+direction[0]*step
... new_y=pos[1]+direction[1]*step
... pos[0]=new_x
... pos[1]=new_y
... return pos
... return go
...
>>> player = create()
>>> print(player([1,0],10))
[10, 0]
>>> print(player([0,1],20))
[10, 20]
>>> print(player([-1,0],10))
[0, 20]
>>>print('player:',player)
function: <function create.<locals>.go at 0x02F94660>
>>> print('function:',go)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'go' is not defined
>>> print('function:',create)
function: <function create at 0x02E4D540>
注意:
- 闭包无法修改外部函数的局部变量
- python循环中不包含域的概念
- 闭包可以保存当前的运行环境
# >>> def outerFunc(): ... x = 0 ... def innerFunc(): ... x = 1 ... print('inner x:',x) ... print('outer x before call inner:',x) ... innerFunc() ... print('outer x after call inner:',x) ... >>> >>> outerFunc() outer x before call inner: 0 inner x: 1 outer x after call inner: 0 >>> #按照正常的理解下面的程序应该输入0,2,4,对吧? 但实际输出的是4,4,4,循环在Python中没有遇到概念,flist在向列表中添加func的时候,并没有保存i的值而当执行f(2)的时候才去取,这时候循环已经结束,i的值是2,所以结果都是4 >>> flist = []>>> for i in range(3): ... def func(x): ... return x*i ... flist.append(func) ... >>> for f in flist: ... print(f(2)) ... 4 4 4 #修改方案 >>> flist = [] >>> for i in range(3): ... def makefunc(i): ... def func(x): ... return x*i ... return func ... flist.append(makefunc(i)) ... >>> for f in flist: ... print(f(2)) ... 0 2 4 >>> #(f是一个函数 序列) 在func外面再定义一个makefunc函数,func形成闭包