我们前面讲高阶函数的时候,已经很多次的提到了lambda,它是一个表达式,也是Python中的匿名函数,我们知道,lambda可以当做函数来使用,返回值就是lambda表达式的结果,lambda也可以当做函数的返回值,比如我们讲到的素数求解,其中有个函数就是这样写的:
我们使用lambda表达式的目的不是为了能替代函数,而是尽可能的替代一些简单的函数,注意是简单的。
插播一个修改Wing自动代码补全键值的方法:
我们看个对比,前面也讲过,是一带而过的那种,下面我们再细致一点:
其实就是一个表达式,返回值就是表达式的结果,理解和用起来不是太难,唯一可讲的地方,就是和一些函数的结合使用,它充当着小弟的角色,哪里需要就出现在哪里。
我们现在知道Python的 lambda表达式,非常简洁,那其他语言呢?下面呢,我们就通过一个例子,来对比一下C#和Python的lambda表达式:
例子:
大环境 :有一个学生类,类里面有三个成员变量,姓名,性别和年龄
添加学生对象 :我们分别创建三个学生对象,并用集合list保存
我们要做的 :筛选这个list集合,我们只要年龄小于18岁的学生
A、C#
Lambda表达式
"Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量。它可以包含表达式和语句
格式:例如x => x * x,=> 读作 goes to, 整个式子的意思就是 x 最终等于 x * x 的结果< --> x goes to x*x
我们看我们的demo实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Student {
private string Sname;//学生姓名
private string Ssex ;//性别
private int Sage ;//年龄
public Student(string name,string sex,int age)
{
this.Sname = name;
this.Ssex = sex ;
this.Sage = age ;
}
public string Sex
{
get { return Ssex; }
set { Ssex = value; }
}
public string Name
{
get { return Sname; }
set { Sname = value; }
}
public int Age
{
get { return Sage; }
set { Sage = value; }
}
}
class Program
{
static void Main(string[] args)
{
Student s1 = new Student("张三","男",22);
Student s2 = new Student("李婷","女",15);
Student s3 = new Student("李四","男",17);
List list = new List();
list.Add(s1);
list.Add(s2);
list.Add(s3);
IEnumerable results = list.Where(Student => Student.Age < 18);
Console.WriteLine("筛选出年龄小于18岁的学生集合:");
foreach(Student s in results)
{
Console.WriteLine("姓名: "+s.Name+",性别: "+s.Sex+",年龄: "+s.Age.ToString());
}
}
}
resuls是一个可迭代的对象集合,在Python中,我们可以通过for循环进行遍历,也可以用iter()函数获得迭代器,通过next进行逐一遍历,在C#中,我们就用foreach,依次取出results里面的 Student对象,然后对对象进行信息打印,我们也发现,上述的lambda表达式,是作用在list上的,这点和Pyhon是不是一样,我们在Python中见到lambda表达式的地方也都是作用在一个可以迭代的对象上的,比如map、filter、sorted等函数,我们发现C#的lambda表达式好像没有Python的简洁,虽然实现的功能一样,因为C#是强类型,而Python是弱类型,因此,你会发现,Python中替我们省去了很多demo,不说了,我们看下C#的实现:
结果就不用解释了,下面我们来观望一下Python,同样的思路,同样的构造类和成员变量,同样使用lambda表达式,返回同样的结果,我们的Python是怎么做的:
B、Python
demo如下:
#/usr/bin/env Python3
#-*- encoding:UTF-8 -*-
class Student(object): #定义一个学生类,该类继承自object
def __init__(self, name, sex,age): #Python的成员变量属性一体化
self.name = name
self.sex = sex
self.age = age
#我们创建三个学生对象
s1 = Student("张三","男",22)
s2 = Student("李婷","女",15)
s3 = Student("李四","男",17)
#我们用list存放这三个对象
L = []
L.append(s1)
L.append(s2)
L.append(s3)
#我们通过lambda表达式(匿名函数)用filter过滤掉年龄小于18岁的学生集合
#过滤后得到一个新的的迭代器,我们list转换一下再次交付给L
L = list(filter(lambda s:s.age<18,L))
print('筛选出年龄小于18岁的学生集合:')
#注意,下面我们对L进行遍历,s其实是一个Student对象,因此,访问name这里不能利用索引s[0],No!
#正确的访问类中的成员变量应该 --> 对象.成员变量 --> s.name
for s in L:
print("姓名: ",s.name,",性别: ",s.sex+",年龄: ",s.age)
我们整体看Python的代码实现,我们发现,咋一看,我们有点蒙,不是因为它有多么的复杂,反而是因为,它太简洁了,简洁的我们都不敢相信这样的demo也可以实现我们的功能,代码量可是比C#的少将近一半。尤其是过滤的部分,我们的Python内建了过滤函数filter,因此我们可以很轻松的结合lambda表达式重新产生一个迭代器Iterator,对于C#来说,还需要另外定义一个枚举器来存放lambda表达式的结果,再对比类,显然Python的更加出色,但是比较抽象,好在,我们写代码的时候,可以省不少事。
我们看下Python的执行结果:
通过本篇的学习,我们对lambda算是比较熟悉了吧,确实很好用,但是我们也别太"依赖"它,为什么这样说呢,比如你要实现一个复杂的函数,你想到了我们学过的lambda,而你又不知道这个函数用lambda该怎么写,于是你就在那折腾,折腾老半天最终发现,还是写不出来,那请记住,不是所有的函数都能用lambda表达式来代替,它是有局限性的,如果你能写出来lambda,就写,写不出来,就用函数吧,别问我为什么,因为我也写不出来。
结束语:
学无止境啊,学的越多,接触的越多,反而觉得自己不会的也太多,敢说自己在某一方面精通的人,要么是吹出来的,要么就是真本事,我钦佩后者。
“会当凌绝顶,一览众山小” -- 送给正在学习路上的我们,以此勉励。