Last Updated on

前言

在网上,常把lambdamap,filter,reduce方法与函数式编程联系在一起,其实吧,我觉得这些方法确实是函数式编程思想的一些相关体现,但是完全没有什么特别必要的联系。感觉更多是东抄西抄,也没有认真去理解。

这里说下我的理解吧,首先,函数式编程,并不是一个新词汇,就像面向对象编程一样,是是一种编程范式(programming paradigm),也就是如何编写程序的方法论。

具体对函数式编程的定义,可以参考此文章:《函数式编程初探》

在实际中,使用什么编程方式,我们不讨论,我们更多的是要明白,这些Python中的内置函数为什么要使用,在哪使用,怎么使用罢了。

所以,下面我就详细举例说明一下这几个内置的体现了函数式编程方式的几个内置函数。

lambda

lambda函数也叫匿名函数,表达式单行定义,返回一个函数对象。

lambda表达式格式:

 lambda *args,**kwargs : expression

中间通过:来分割,: 前的是参数,: 后的是运行逻辑的表达。具有以下特点和注意事项:

  • 单行定义
  • 可不接受参数
  • 内部不能创建变量,只能调用自己的形参或已定义的对象。
  • 返回一个函数对象,调用时才会执行

看以下示例:

单行定义,返回一个函数对象:

a = lambda x, y: x + y
print(a(1,2))
print(a)

# 输出结果: 
3
<function <lambda> at 0x1020bae18>

可不接收参数:

s = lambda: 10
print(s())

# 输出结果: 10

当调用时才会执行,执行时全局的变量 i 已经为9,所以返回的结果全是109:

a = [lambda:100+i for i in range(10)]
for x in a:
    print(x())

# 输出结果:全为109

当修改不可变对象时,会返回新的对象,当修改可变对象时,返回None

func1=lambda info:info.split(",")
print(func1("a,b,c"))

# 输出结果:
["a","b","c"]


func1=lambda info:info.append("a")
print(func1([]))

# 输出结果
None

# 等同于:
def func(info):
    return info.append("a")

以上,列举了lambda的定义和使用时,一些常见的注意事项和特点。

那么,lambda函数在什么地方使用呢?lambda由于其特点。一般在具有以下情况的时候,选择使用:

  • 小函数,简单任务,一行完成
  • 只用一次

lambda函数也常被用于与map(),filter(),reduce()函数进行配合使用。

map()

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的一个可迭代的map对象。

语法格式为:

map(function, iterable, ...)

常用于与lambda配合使用。比如:

a = map(lambda x:x*2,[1,2,3])
print(a)
for x in a:
    print(x)

print(list(a))
# 输出结果:
<map object at 0x10511f780>
2
4
6
[]

如上所示,返回的map对象是一个类似于生成器的可迭代对象,只能迭代一次

filter()

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。

该接收两个参数,第一个为函数,第二个为可迭代对象,可迭代对象的每个元素作为参数传递给函数进行判断,最后将返回 True 的元素放到新的迭代对象,返回一个filter对象,与map类似。

语法格式为:

filter(function, iterable)

常用于与lambda配合使用。比如:

a = filter(lambda x: x < 2, [1, 2, 3])
print(a)

for i in a:
    print(i)
print(list(a))

# 输出结果:
<filter object at 0x106cf7780>
1
[]

与map相同,返回的filter对象是一个类似于生成器的可迭代对象,只能迭代一次

reduce()

reduce()是对一个序列的每个项迭代调用函数,并将结果带入参数累计调用。

在 Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 functools 模块里。

语法格式为:

reduce(function, sequence, initial=None)

PS: 传入的函数,必须为两个参数! initial为初始值,选填。

详细的,先看下面示例:

from functools import reduce
a = reduce(lambda x, y: x + y, [[1], [2], [3], [4], [5]])
print(a)
print(type(a))

# 输出结果:
[1, 2, 3, 4, 5]
<class 'list'>


b = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(b)
print(type(b))

# 输出结果:
15
<class 'int'>


c = reduce(lambda x, y: int(x) + int(y), ['1', '2', '3', '4', '5'])
print(c)
print(type(c))

# 输出结果:
15
<class 'int'>

如上,reduce函数会将可迭代对象的第一个和第二个值传入函数,然后将返回结果作为第一个参数,可迭代对象的下一个值作为第二个参数,继续调用函数,然后以此循环,最后返回结果,如果函数有initial初始值,则第一次调用时,传入初始值和可迭代对象的第一个元素。

另外,对于返回的对象的属性,这取决与可迭代对象的元素的属性和函数方法


OK,关于lambdamapfilterreduce函数的使用介绍就到这里。

有任何问题,欢迎留言。