写在之前
今天给大家介绍几个比较特殊的函数, 他们具有函数式编程的特点, 有人将它们视为 Python 可进行 "函数式编程" 的见证, 至于什么是函数式编程, 不是本篇文章的重点, 感兴趣的可以去了解一下. 老读者可能都知道, 我非常推崇 Python 的简洁优雅, 而今天的这几个函数, 有了它们, 最大的好处就是可以让程序更简洁, 当然, 没有它们程序也可以用其它方式实现.
lambda 函数
lambda 是一个可以只用一行就能解决问题的函数, 让我们先看下面的例子:
- >>> def add(x):
- ... x += 1
- ... return x
- ...
- >>> numbers = range(5)
- >>> list(numbers)
- [0, 1, 2, 3, 4]
- >>> new_numbers = []
- >>> for i in numbers:
- ... new_numbers.append(add(i))
- ...
- >>> new_numbers
- [1, 2, 3, 4, 5]
在上面的这个例子中, 函数 add() 充当了一个中间角色, 当然上面的例子也可以如下实现:
- >>> new_numbers = [i+1 for i in numbers]
- >>> new_numbers
- [1, 2, 3, 4, 5]
首先我要说, 上面的列表解析式其实是很好用的, 但是我偏偏要用 lambda 这个函数代替 add(x) :
- >>> lamb = lambda x: x+1
- >>> new_numbers = []
- >>> for i in numbers:
- ... new_numbers.append(lamb(i))
- ...
- >>> new_numbers
- [1, 2, 3, 4, 5]
在这里的 lamb 就相当于 add(x) ,lamb = lambda x : x+1 就相当于 add(x) 里的代码块. 下面再写几个应用 lambda 的小例子:
- >>> lamb = lambda x,y : x + y
- >>> lamb(1,2)
- 3
- >>> lamb1 = lambda x : x ** 2
- >>> lamb1(5)
- 25
由上面的例子我们可以总结一下 lambda 函数的具体使用方法: lambda 后面直接跟变量, 变脸后面是冒号, 冒号后面是表达式, 表达式的计算结果就是本函数的返回值.
在这里有一点需要提醒的是, 虽然 lambda 函数可以接收任意多的参数并且返回单个表达式的值, 但是 lambda 函数不能包含命令且包含的表达式不能超过一个. 如果你需要更多复杂的东西, 你应该去定义一个函数.
lambda 作为一个只有一行的函数, 在你具体的编程实践中可以选择使用, 虽然在性能上没什么提升, 但是看着舒服呀.
map 函数
我们在上面讲 lambda 的时候用的例子, 其实 map 也可以实现, 请看下面的操作:
- >>> numbers = [0,1,2,3,4]
- >>> map(add,numbers)
- [1, 2, 3, 4, 5]
- >>> map(lambda x: x + 1,numbers)
- [1, 2, 3, 4, 5]
map 是 Python 的一个内置函数, 它的基本格式是: map(func, seq).
func 是一个函数对象, seq 是一个序列对象, 在执行的时候, seq 中的每个元素按照从左到右的顺序依次被取出来, 塞到 func 函数里面, 并将 func 的返回值依次存到一个列表里.
对于 map 要主要理解以下几个点就好了:
1. 对可迭代的对象中的每一个元素, 依次使用 fun 的方法 (其实本质上就是一个 for 循环).
2. 将所有的结果返回一个 map 对象, 这个对象是个迭代器.
我们接下来做一个简单的小题目: 将两个列表中的对应项加起来, 把结果返回在一个列表里, 我们用 map 来做, 如果你做完了, 请往下看:
- >>> list1 = [1,2,3,4]
- >>> list2 = [5,6,7,8]
- >>> list(map(lambda x,y: x + y,list1,list2))
- [6, 8, 10, 12]
你看上面, 是不是很简单? 其实这个还看不出 map 的方便来, 因为用 for 同样也不麻烦, 要是你有这样的想法的话, 那么请看下面:
- >>> list1 = [1,2,3,4]
- >>> list2 = [5,6,7,8]
- >>> list3 = [9,10,11,12]
- >>> list(map(lambda x,y,z : x + y + z,list1,list2,list3))
- [15, 18, 21, 24]
你看三个呢? 是不是用 for 的话就稍显麻烦了? 那么我们在想如果是 四个, 五个乃至更多呢? 这就显示出 map 的简洁优雅了, 并且 map 还不和 lambda 一样对性能没有什么提高, map 在性能上的优势也是杠杠的.
filter 函数
filter 翻译过来的意思是 "过滤器", 在 Python 中, 它也确实是起到的是过滤器的作用. 这个解释起来略微麻烦, 还是直接上代码的好, 在代码中体会用法是我在所有的文章里一直在体现的:
- >>> numbers = range(-4,4)
- >>> list(filter(lambda x: x> 0,numbers))
- [1, 2, 3]
上面的例子其实和下面的代码是等价的:
- >>> [x for x in numbers if x> 0]
- [1, 2, 3]
然后我们再来写一个例子体会一下:
- >>> list(filter(lambda x: x != 'o','Rocky0429'))
- ['R', 'c', 'k', 'y', '0', '4', '2', '9']
reduce 函数
我在之前的文章中很多次都说过, 我的代码都是用 Python3 版本的. 在 Python3 中, reduce 函数被放到 functools 模块里, 在 Python2 中还是在全局命名空间.
同样我先用一个例子来跑一下, 我们来看看怎么用:
- >>> reduce(lambda x,y: x+y,[1,2,3,4])
- 10
reduce 函数的第一个参数是一个函数, 第二个参数是序列类型的对象, 将函数按照从左到右的顺序作用在序列上. 如果你还不理解的话, 我们下面可以对比一下它和 map 的区别:
- >>> list1 = [1,2,3,4]
- >>> list2 = [5,6,7,8]
- >>> list(map(lambda x,y: x + y,list1,list2))
- [6, 8, 10, 12]
对比上面的两个例子, 就知道两者的区别, map 相当于是上下运算的, 而 reduce 是从左到右逐个元素进行运算.
写在之后
至此, 我在上面介绍了四个函数, 这些函数不仅使得代码更加的简单, 而且在 Python3 中也优化了它们的性能. 所以如果你喜欢的话, 尽可以放心大胆的使用.
来源: https://www.cnblogs.com/Rocky0429/p/10147714.html