Pyhton学习九 函数式编程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_43426335/article/details/98638187

加粗样式@[toc]

函数式编程

面向过程的程序设计
基本单元,函数
函数时编程:允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

高阶函数

abs(-10)是函数调用,abs是函数本身
要获得调用结果,我们可以把结果赋值给变量
也可以把函数本身赋给变量,即变量指向函数,这样可以实现通过变量来调用函数

>>> abs
<built-in function abs>
>>> f=abs
>>> f(-10)
10

说明变量f现在已经指向了abs函数本身,直接调用abs()函数和调用f()完全相同

函数名也是变量
函数名就是指向函数的变量,

如果把abs指向其他对象呢?

>>> abs(-2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

指向其他对象后,就暂时没有原来功能了

传入函数

高阶函数,在一个函数中能调用另一个函数

map/reduce

map

>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

map()传入的第一个参数是函数对象f,

L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    L.append(f(n))
print(L)

reduce 看官网吧

filter

正确实现筛选功能
用于过滤序列,例如删掉偶数只保留奇数,把一个序列的空字符串去掉

def not_empty(s):
	return s and s,strip()
list(filter(not_empty,['A','','B',None ,'c','d']))
#结果是 ['A','b','c']

sorted(排序算法)

内置sorted()函数可以对list排序

>>> sorted([1,2,7,6,5,4])
[1, 2, 4, 5, 6, 7]

sorted()函数也是一个高阶函数,他还可以接收一个key函数来实现自定义的排序,例如按照绝对值大小排序

>>> sorted([3,5,-1,-2],key=abs)
[-1, -2, 3, 5]

key指定的函数将作用在list的每一个元素上,并根据key函数返回的结果进行排序,对比原来的list和经过key=abs处理过的lsit:

>>> sorted([3,5,-1,-2],key=abs)
[-1, -2, 3, 5]

然后按照key进行排序

sort也可以给字符串排序

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']

按照accii码值来排序的

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']

要进行反向排序,不必改动key,可以传入的三个参数reverse=Ture

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']

高阶函数的抽象能力是非常强大的,而且核心代码可以保持非常简洁

函数作为返回值

写完一个求和函数后,不需要立刻求和,而是在后面的代码中根据需要再计算怎么办,可以不返回求和的结果,而是返回求和的函数

返回函数没有立刻执行,而是在主函数中调用了才被执行

闭包

在IDLE中写程序的时候要在最后加上print(),因为他不是交互环境!!!

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

f1,f2,f3= count()#借用count来调用函数!!!
print(f1())
print(f2())
print(f3())

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

如果一定要引用循环变量,需要再创建一个函数,用该函数的参数绑定循环变量的值

def count():
    def f(j):
        def g():
            return j*j
        return g
    fs=[]
    for i in range(1,4):
        fs.append(f(i))#f立刻被执行,因此i的当前值被传入f()
    return fs
f1,f2,f3 = count()
print(f1())
print(f2())

缺点:代码较长,可利用lambda函数缩短代码

小结:
一个函数可以返回一个计算结果,也可以返回一个函数。
返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的量。

匿名函数

好处:因为函数没有名字,不必担心函数名冲突
没有return语句

s=list(map(lambda x:x*x,[1,2,3,4,5,6,7,8,9]))
print(s)
实际上就是
def f(x):
	return x*x

关键字lambda表示匿名函数,冒号前面的x表示函数参数
匿名函数有个限制,就是只能有一个表达式,不用写return语句,返回值就是该表达式的结果
匿名函数也是一个函数对象,可以把匿名函数赋给一个变量,再利用变量+参数 来调用函数,

f=lambda x:x*x
print(f(4))

可以把匿名函数作为返回值返回

装饰器

在代码运行期间动态增加功能的方式,称之为“装饰器”decoator

偏函数

int转换其他类型的时候,默认按十进制转换
要想转化为二进制 int(x,base=2)
如果嫌一直写太麻烦,可以定义一个函数啊

def int2(x,base=2):
	return int(x,base)

偏函数
functools.partial帮助我们创建一个偏函数,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数

import functools
int2=functools.partial(int base=2)
int2('100000')
64

funtools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

小结:
当函数的参数过多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用的时候更简单。

猜你喜欢

转载自blog.csdn.net/qq_43426335/article/details/98638187