Python中的lambda

我在使用python的时候,其实很少用到lambda函数,但总会在别人的代码中看到别人使用,有的时候理解起来还是会有点头疼,就特意地全面地学习了一下lambda的使用。

1. 什么是lambda?

lambda大致的语法结构如下:

lambda arguments_list: expression

lambda函数可以输入多个参数,参数与参数之间可以用逗号分开。而参数与表达式之间,可以使用冒号分开;

1
2
3
4
In [1]: f = lambda x, y : x * y

In [2]: f(2,3)
Out[2]: 6

2. lambda的作用

第一,我认为 lambda函数能够使代码看起来更加简洁,注意,它并不会带来运行效率的提升。但是对于看代码的人来说,理解起来会有难度,特别是在不熟悉代码的情况下。所以,从我个人的角度来讲,还是尽量使用for xx in xx if去代替lambda。

第二,在一些特殊的情况下,只需要一次性的函数,那么可以考虑使用lambda去定义。

第三,lambda语法构造的函数,可以认为是一个表达式,定义了一个匿名函数。

3. lambda相关函数map() / filetr() / reduce()

通常lambda会和python中的三个函数map(), filter(), reduce()配合使用。下面也做一个简单介绍。

python2: map,filter,reduce均为全局函数;
python3: map和filter仍为全局函数,reduce被放入到functools库中;

3.1 map()函数

map函数的语法结构如下:

map(function_object, iterable1, iterable2,...)

map函数需要一个函数对象和任意数量的迭代器,比如list,dict等。

在python2中使用map,可以看到可以直接返回一个list结果。

1
2
3
4
5
6
7
8
>>> def add(x, y):
... return x + y
...
>>> map(add, [1, 2, 3], [4, 5, 6])
[5, 7, 9]
>>>
>>> map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
[5, 7, 9]

在python3中使用map,返回的是一个迭代器或者是map对象,需要用list()做一个强行转换,才能打印出结果。
这么做的原因主要是想做到“惰性计算”(Lazy Evaluation),也被成为是 call by need。说白了就是需要的时候调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> def add(x, y):
... return x + y
...
>>> map(add, [1, 2, 3], [4, 5, 6])
<map object at 0x7f115cfac860>
>>>
>>> list(map(add, [1, 2, 3], [4, 5, 6]))
[5, 7, 9]
>>>
>>> map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
<map object at 0x7f115cfac828>
>>>
>>> list(map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6]))
[5, 7, 9]
>>>

3.2 filter()函数

filter函数的语法结构如下:

filter(function_object, iterable)

filter函数需要传入一个函数对象和和一个迭代器(仅有一个迭代器),这里要求函数对象返回的是一个布尔型的值,filter根据函数对象的返回值,来过滤迭代器中的元素。那些判断为true的元素会被返回。

在python3 中的一个例子,跟map一种,返回的同样是一个filter对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> def is_odd(x):
... if x % 2 == 0:
... return False
... else:
... return True
...
>>> filter(is_odd, [1, 2, 3, 4, 5, 6])
<filter object at 0x7f115cfac8d0>
>>> list(filter(is_odd, [1, 2, 3, 4, 5, 6]))
[1, 3, 5]
>>>
>>> filter(lambda x: x % 2 != 0, [1, 2, 3, 4, 5, 6])
<filter object at 0x7f115cfac8d0>
>>> list(filter(lambda x: x % 2 != 0, [1, 2, 3, 4, 5, 6]))
[1, 3, 5]

举个dict的例子

1
2
3
>>> dict_a = [{'name': 'python', 'points': 10}, {'name': 'java', 'points': 8}]
>>> list(filter(lambda x : x['name'] == 'python', dict_a))
[{'name': 'python', 'points': 10}]

3.3 reduce()函数

reduce函数的语法结构如下:

reduce(function_object, sequence)

reduce函数需要传入一个函数对象和序列,reduce函数会将序列中的前两个元素作为参数传给函数对象,得到返回值,将返回值与序列中的第三个值作为参数再次传入给函数对象,以此类推。。

python2中该函数为全局变量

1
2
>>> reduce(lambda x, y : x + y, [1, 2, 3, 4]) 
10

python3中该函数被放到functools中,需要先导入functools库。

1
2
3
>>> import functools
>>> functools.reduce(lambda x, y : x + y, [1, 2, 3, 4])
10