匿名函数lambda表达式
什么是匿名函数?
匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑。lambda 本质上是一个函数对象,可以将其赋值给另一个变量,再由该变量来调用函数,也可以直接使用。
1
2
3
4
5
6
7
8
9
10
11
12
|
#平时,我们是先定义函数,再进行调用 def power(x): return x * * 2 print (power( 2 )) #使用lambda表达式的时候,我们可以这样操作 power = lambda x : x * * 2 print (power( 2 )) #觉得太麻烦,还可以这样调用 print (( lambda x: 2 * x)( 8 )) |
lambda表达式的基本格式:lambda 入参 : 表达式
1
2
3
4
|
#入参可以有多个,比如 power = lambda x, n: x * * n print (power( 2 , 3 )) |
lambda 表达式的使用场景
一般适用于创建一些临时性的,小巧的函数。比如上面的 power函数,我们当然可以使用 def 来定义,但使用 lambda 来创建会显得很简洁,尤其是在高阶函数的使用中。
定义一个函数,传入一个list,将list每个元素的值加1
1
2
3
4
|
def add(l = []): return [x + 1 for x in l] print (add([ 1 , 2 , 3 ])) |
上面的函数改成将所有元素的值加2
可能大家会说,这还不简单,直接把return里的1改成2就行了。但是真的行吗?如果函数被多个地方使用,而其他地方并不想加2,怎么办?
这好办,把变得那部分抽出来,让调用者自己传
1
2
3
4
5
6
7
8
9
10
11
|
def add(func,l = []): return [func(x) for x in l] def add1(x): return x + 1 def add2(x): return x + 2 print (add(add1,[ 1 , 2 , 3 ])) print (add(add2,[ 1 , 2 , 3 ])) |
一个简简单单的问题,一定要用这么多代码实现?
1
2
3
4
5
|
def add(func,l = []): return [func(x) for x in l] print (add( lambda x:x + 1 ,[ 1 , 2 , 3 ])) print (add( lambda x:x + 2 ,[ 1 , 2 , 3 ])) |
map函数
map的基本格式
map(func, *iterables)
map() 函数接收两个以上的参数,开头一个是函数,剩下的是序列,将传入的函数依次作用到序列的每个元素,并把结果作为新的序列返回。也就是类似 map(func,[1,2,3])
同样的,我们还是来完成这样一个功能:将list每个元素的值加1
1
2
3
4
5
6
|
def add(x): return x + 1 result = map (add, [ 1 , 2 , 3 , 4 ]) print ( type (result)) print ( list (result)) |
使用lambda表达式简化操作
1
2
3
|
result = map ( lambda x: x + 1 , [ 1 , 2 , 3 , 4 ]) print ( type (result)) print ( list (result)) |
函数中带两个参数的map函数格式
使用map函数,将两个序列的数据对应位置求和,之后返回,也就是对[1,2,3],[4,5,6]两个序列进行操作之后,返回结果[5,7,9]
1
|
print ( list ( map ( lambda x, y: x + y, [ 1 , 2 , 3 ], [ 4 , 5 , 6 ]))) |
对于两个序列元素个数一样的,相对好理解。如果两个序列个数不一样的,会不会报错?
1
|
print ( list ( map ( lambda x, y: x + y, [ 1 , 2 , 3 ], [ 4 , 5 ]))) |
我们可以看到不会报错,但是结果以个数少的为准
reduce函数
reduce函数的基本格式
reduce(function, sequence, initial=None)
reduce把一个函数作用在一个序列上,这个函数必须接收两个参数,reduce函数把结果继续和序列的下一个元素做累积计算,跟递归有点类似,reduce函数会被上一个计算结果应用到本次计算中
reduce(func, [1,2,3]) = func(func(1, 2), 3)
使用reduce函数,计算一个列表的乘积
1
2
3
4
5
6
|
from functools import reduce def func(x, y): return x * y print ( reduce (func, [ 1 , 2 , 3 , 4 ])) |
结合lambda表达式,简化操作
1
2
3
|
from functools import reduce print ( reduce ( lambda x, y: x * y, [ 1 , 2 , 3 , 4 ])) |
filter 函数
filter 顾名思义是过滤的意思,带有杂质的(非需要的数据),经过 filter 处理之后,就被过滤掉。
filter函数的基本格式
filter(function_or_None, iterable)
filter() 接收一个函数和一个序列。把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。
使用 filter 函数对给定序列进行操作,最后返回序列中所有偶数
1
|
print ( list ( filter ( lambda x: x % 2 = = 0 , [ 1 , 2 , 3 , 4 , 5 ]))) |
sorted 函数
sorted从字面上就可以看去这是个用来排序的函数,sorted 可以对所有可迭代的对象进行排序操作
sorted的基本格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
sorted (iterable, key = None , reverse = False ) #iterable -- 可迭代对象。 #key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。 #reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。 #对序列做升序排序 print ( sorted ([ 1 , 6 , 4 , 5 , 9 ])) #对序列做降序排序 print ( sorted ([ 1 , 6 , 4 , 5 , 9 ], reverse = True )) #对存储多个列表的列表做排序 data = [[ "Python" , 99 ], [ "c" , 88 ]] print ( sorted (data, key = lambda item: item[ 1 ])) |
闭包
在万物皆对象的Python中,函数是否能作为函数的返回值进行返回呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def my_power(): n = 2 def power(x): return x * * n return power p = my_power() print (p( 4 )) #------------------------------------------------------------ def my_power(): n = 2 def power(x): return x * * n return power n = 3 p = my_power() print (p( 4 )) |
我们可以看到,my_power 函数在返回的时候,也将其引用的值(n)一同带回,n 的值被新的函数所使用,这种情况我们称之为闭包
当我们把n的值移除到my_power函数外面,这个时候来看下计算结果
1
2
3
4
5
6
7
8
9
10
|
n = 2 def my_power(): def power(x): return x * * n return power n = 3 p = my_power() print (p( 4 )) |
为什么输出的结果会是64?
我们先来看看闭包时,p.__closure____的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#例1 def my_power(): n = 2 def power(x): return x * * n return power p = my_power() print (p.__closure__) #结果:(<cell at 0x00000264518F9A38: int object at 0x00007FFA7F617120>) #closure是内部函数的一个属性,用来保存环境变量 #--------------------------------------------------------------------- #例2 n = 2 def my_power(): def power(x): return x * * n return power n = 3 p = my_power() print (p.__closure__) #输出结果 None |
通过例1跟例2对比,我们可以知道,例2并不是闭包
闭包经典问题
下面的程序是否是闭包?能否正确运行
1
2
3
4
5
6
7
8
9
10
11
|
def my_power(): n = 2 def power(x): n + = 1 return x * * n return power p = my_power() print (p( 3 )) |
如何让上面的程序正确运行?看看改正之后的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
def my_power(): n = 2 def power(x): nonlocal n n + = 1 return x * * n return power p = my_power() print (p.__closure__) print (p( 3 )) print (p( 3 )) |
看看下面的程序的运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def my_power(): n = 2 L = [] for i in range ( 1 , 3 ): def power(): return i * * n L.append(power) return L f1, f2 = my_power() print (f1()) print (f2()) print (f1.__closure__[ 0 ].cell_contents) print (f2.__closure__[ 0 ].cell_contents) |
python的函数只有在执行时,才会去找函数体里的变量的值,也就是说你连形参都不确定,你咋求知道 i为几呢?在这里,你只需要记住如果你连形参都不确定,python就只会记住最后一个i值。
装饰器及其应用
什么是装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
1
2
3
4
5
6
|
import time start = time.time() time.sleep( 4 ) end = time.time() print (end - start) |
从实际例子来看装饰器
1
2
3
4
|
def my_fun(): print ( "这是一个函数" ) my_fun() |
要再打印“这是一个函数”前面在打印多一行hello world。
1
2
3
4
5
6
7
8
|
def my_fun(): begin = time.time() time.sleep( 2 ) print ( "这里一个函数" ) end = time.time() print (end - begin) my_fun() |
这个时候,如果不想修改原有的函数,咋整?
1
2
3
4
5
6
7
8
9
10
11
|
def my_fun(): print ( "这是一个函数" ) def my_time(func): begin = time.time() time.sleep( 2 ) func() end = time.time() print (end - begin) my_time(func) |
这种方式,因为要增加功能,导致所有的业务调用方都得进行修改,此法明显不可取。
另一种方式:
1
2
3
4
5
6
7
8
9
10
11
12
|
def print_cost(func): def wrapper(): begin = time.time() time.sleep( 2 ) func() end = time.time() print (end - begin) return wrapper @print_cost def my_fun(): print ( "这里一个函数" ) |
第二种方式并没有修改func函数的内部实现,而是使用装饰器模式对其功能进行装饰增强。
以上就是浅谈Python 函数式编程的详细内容,更多关于Python 函数式编程的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/jwen1994/p/13127205.html