Python学习笔记22:函数式编程

Python学习笔记22:函数式编程

这里的函数式编程,并非指面向过程编程。而更多的是一种将函数作为一等对象的编程语言中,函数在编程中灵活性体现的一种描述。

一等对象

关于什么是一等对象,《Fluent Python》一书给出的解释是——如果一个对象是一等对象,将具有以下特性:

  • 运行时创建

  • 能赋值给变量或容器中的元素

  • 能作为函数参数进行传递

  • 能作为函数的返回值结果

在我的印象中,Javascrip和Python中的函数都具有此类特性,具有相当高的灵活性。而其它语言都缺少这样或那样的特性。

函数对象

正如在Python学习笔记0:变量中阐述过的那样,Python是门基于对象的语言,而函数也是对象。

def hello():
    '''你好'''
    print("Hello world!")

print(hello)
print(type(hello))
print(hello.__doc__)
# <function hello at 0x000001D402AF39D0>
# <class 'function'>
# 你好

通过type我们可以清楚地看到自定义函数hellofunction类的一个实例,而且可以访问其属性,比如__doc__

此外,函数对象还可以作为参数和返回值,这在构建函数修饰符的时候有明确体现,需要回顾和了解的可以阅读Python学习笔记11:函数修饰符,此处不做过多赘述。

高阶函数

我们已经说明了函数本身是可以作为参数进行传递的,而通过参数接收函数的函数被称作高阶函数。

我知道这么说很绕,但意思不难理解。

在Python的常用函数中有这么几个高阶函数:

sorted

sorted常用于序列排序,之前在Python学习笔记19:列表 III中我们介绍过。

我们知道,sorted可以指定一个参数key,改变默认的排序原则。

l = ["aa", "b", "ccc"]
print(sorted(l, key=len))
# ['b', 'aa', 'ccc']

就像上面展示的那样,key通过接收单参数函数对象的方式改变了sorted的默认排序原则。

所以说sort是一个高阶函数。

map

map函数的作用如同其名称揭示的那样,可以将一个函数应用于一个可迭代对象。

persons = [('Jack chen', 16, 'actor'),
           ('Brus lee', 20, 'engineer')]


def formatPerson(person: tuple):
    return "name:%s,age:%s,actor:%s" % (person[0], str(person[1]), person[2])


formatPersons = list(map(formatPerson, persons))
print(formatPersons)
# ['name:Jack chen,age:16,actor:actor', 'name:Brus lee,age:20,actor:engineer']

map的返回值同样是一个可迭代对象,所以我们可以用list()承接并进一步处理。

这个例子中的formatPerson函数比较简单,所以我们也可以用匿名函数来改写:

persons = [('Jack chen', 16, 'actor'),
           ('Brus lee', 20, 'engineer')]

formatPersons = list(map(lambda person: "name:%s,age:%s,actor:%s" % (
    person[0], str(person[1]), person[2]), persons))
print(formatPersons)
# ['name:Jack chen,age:16,actor:actor', 'name:Brus lee,age:20,actor:engineer']

但这样的代码可读性不高,幸运的是Python3提供了两个新的特性:推导式和生成器。我们完全可以用推导式完成类似的工作,还更具有可读性。

persons = [('Jack chen', 16, 'actor'),
           ('Brus lee', 20, 'engineer')]

formatPersons = ["name:%s,age:%s,actor%s" % (name,age,career) for name,age,career in persons]
print(formatPersons)
# ['name:Jack chen,age:16,actor:actor', 'name:Brus lee,age:20,actor:engineer']

所以,因为推导式和生成器的存在,map在Python3中的使用频率不高。

reduce

reduce函数接受一个两参数函数,会用这个函数来处理一个可迭代对象。

map不同的是,reduce函数的处理逻辑是“累积式处理”。即每处理完一个可迭代对象的元素,会把其结果作为下一次处理中的一个参数。

这种处理方式的最常见概念是数学中的阶乘

image-20210417141457335

我们使用reduce来完成一个阶乘函数:

from functools import reduce


def factorial(n):
    return reduce(lambda a, b: a*b, range(1, n+1))


print(factorial(1))
print(f
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值