lambda表达式

c++

##c++中的lambda表达式


#####什么是lambda表达式
c++中,一个lambda表达式表示一个可调用的代码单元。可以将其理解为一个未命名的内联函数。与函数类似,一个lambda具有一个返回类型、一个参数列表、和一个函数体。但lambda可以定义在函数内部。一个lambda表达式具有如下形式:
[capture list](parameter list) -> return type { function body }
capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空);parameter list, return type和function body和任何普通函数一样,分别表示参数列表、返回类型和函数体。与普通函数不同,lambda必须使用尾置返回来指定返回类型。


#####应用
在c++中,lambda主要作为算法的可调用对象。可以向算法传递的可调用对象(callable object)包括函数和函数指针,重载了函数调用运算符的类以及lambda表达式。
假如现在想把一个vector中的元素按照逆序排序,可以向sort算法传递函数:

1
2
bool cmp(const int a, const int b) { return a > b; }
sort(ivec.begin(), ivec.end(), cmp);

也可以自己定义一个重载了函数调用运算符()的类

1
2
3
4
5
6
7
class Cmp {
pubilc:
bool operator() (const int a, const int b) const
{ return a > b; }
};

sort(ivec.begin(), ivec.end(), Cmp());

当然也可以直接用头文件中的函数对象:

1
2
#include <functional>
sort(ivec.begin(), ivec.end(), greater<int>());

最后一种方式就是使用lambda:

1
2
3
//c++11
sort(ivec.begin(), ivec.end(),
[](const int a, const int b) { return a > b; });

需要用g++ -std=c++11编译。lambda表达式很容易理解:
[](const int a, const int b) { return a > b; }
捕获列表为空,之后是形参列表,后边是函数体。
什么时候需要用捕获列表呢?假如你想统计一个vector中有多少string的长度大于sz,可以这么用:

1
2
int cnt = count_if(svec.begin(), svec.end(), 
[sz](const string &s) { return a.size() >= sz; });

把sz放到捕获列表中就可以统计有多少长度大于sz的string。
可见c++解决问题的方法很多,lambda简化了可调用对象的构建。


##python中的lambda表达式


#####匿名函数与lambda
在python中,一个完整的lambda“语句”代表一个表达式,这个表达式的定义体必须和声明放在同一行。python中lambda语法如下:
lambda [arg1[, arg2, ... argN]]: experssion
中间的[, arg2, … argN]代表可选行参。python允许用lambda关键字创建匿名函数。lambda表达式返回可调用的函数对象。lambda运作起来就像一个函数,但被调用时,创建一个框架对象。


#####示例
不带参数的lambda:

1
2
3
4
5
6
>>> def true(): return True  #定义一个函数,python中但单行函数可以和标题同行
>>> lambda: True #等价的lambda表达式

>>> fun = lambda: True
>>> fun() #调用fun()
True

带参数的lambda:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> def add(x, y): return x + y
>>> lambda x, y: x + y #add的等价lambda
>>> fun1 = lambda x, y: x + y
>>> fun1(1, 2)
3

>>> def add2(x, y=2) : return x + y
>>> lambda: x, y=2: x + y #带默认行参的等价add2 lambda
>>> fun2 = lambda x, y = 2: x + y
>>> fun2(1)
3

>>> def showTuple(*z); return z # *z表示tuple型可变参数
>>> lambda: *z: z
>>> fun3 = lambda *z: z
>>> fun3(1, 'xyz')
(1, 'xyz')
>>> fun3(42)
(42,)

######参考
《c++ Primer Fifth Edition》
《Python核心编程》