Python3学习(16)--匿名函数lambda

我们前面讲高阶函数的时候,已经很多次的提到了lambda,它是一个表达式,也是Python中的匿名函数,我们知道,lambda可以当做函数来使用,返回值就是lambda表达式的结果,lambda也可以当做函数的返回值,比如我们讲到的素数求解,其中有个函数就是这样写的:

我们使用lambda表达式的目的不是为了能替代函数,而是尽可能的替代一些简单的函数,注意是简单的。

插播一个修改Wing自动代码补全键值的方法:

 修改方法:edit  -> preferences -> Editor -> Auto-completion

 把右边keys的地方,从tab改成enter




我们看个对比,前面也讲过,是一带而过的那种,下面我们再细致一点:


其实就是一个表达式,返回值就是表达式的结果,理解和用起来不是太难,唯一可讲的地方,就是和一些函数的结合使用,它充当着小弟的角色,哪里需要就出现在哪里。



我们现在知道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<Student> list = new List<Student>();
            list.Add(s1);
            list.Add(s2);
            list.Add(s3);

            IEnumerable<Student> 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面向对象部分,我们后续会讲到;

我们整体看Python的代码实现,我们发现,咋一看,我们有点蒙,不是因为它有多么的复杂,反而是因为,它太简洁了,简洁的我们都不敢相信这样的demo也可以实现我们的功能,代码量可是比C#的少将近一半。尤其是过滤的部分,我们的Python内建了过滤函数filter,因此我们可以很轻松的结合lambda表达式重新产生一个迭代器Iterator,对于C#来说,还需要另外定义一个枚举器来存放lambda表达式的结果,再对比类,显然Python的更加出色,但是比较抽象,好在,我们写代码的时候,可以省不少事。


我们看下Python的执行结果:



通过本篇的学习,我们对lambda算是比较熟悉了吧,确实很好用,但是我们也别太"依赖"它,为什么这样说呢,比如你要实现一个复杂的函数,你想到了我们学过的lambda,而你又不知道这个函数用lambda该怎么写,于是你就在那折腾,折腾老半天最终发现,还是写不出来,那请记住,不是所有的函数都能用lambda表达式来代替,它是有局限性的,如果你能写出来lambda,就写,写不出来,就用函数吧,别问我为什么,因为我也写不出来。


结束语:

学无止境啊,学的越多,接触的越多,反而觉得自己不会的也太多,敢说自己在某一方面精通的人,要么是吹出来的,要么就是真本事,我钦佩后者。


“会当凌绝顶,一览众山小”  -- 送给正在学习路上的我们,以此勉励。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值