Python学习(13)--Lambda表达式和switch语句的实现

简介: Python学习(13)--Lambda表达式和switch语句的实现 1.Lambda表达式定义匿名函数          在Python中,Lambda表达式是用来快速定义一个最小函数,这个函数小到什么程度呢,小到只有一行代码,一条语句,在Python中有时候我们为了提高程序的可读性,或者一.

Python学习(13)--Lambda表达式和switch语句的实现

1.Lambda表达式定义匿名函数

         在Python中,Lambda表达式是用来快速定义一个最小函数,这个函数小到什么程度呢,小到只有一行代码,一条语句,在Python中有时候我们为了提高程序的可读性,或者一个功能块小到我们并不需要定义一个函数来实现它的时候就用到了Lambda表达式,那么什么又是Lambda表达式呢?下面我们通过一个代码例子来了解下:

[python] view plain copy

  1. def f(x,y):
  2.     return x*y
  3. g=lambda x,y:x*y
  4. print(g(2,3))

如上所示,开始我们定义了一个常见的函数f(x,y),这个函数的功能很简单,就是返回两个形式参数x和y的乘积,函数的名字为f。lambda x,y:x*y一句就定义了一个极简的函数,这个函数是匿名的,参数列表为x和y,返回值就是x*y,不需要特定的return语句返回,lambda表达式返回的是一个函数对象,这个函数对象我们用g来接收它,当调用这个函数时,也是用g这个函数对象来调用,如g(2,3)就是调用lambda表达式返回的函数。以下是对一个lambda表达式各个部分的详细注解.

      
       Lambda表达式更加精简,有时候我们可能并不需要调用一个函数模块很多次,或者这个函数的命名并不容易,而这个函数模块又特别简单,简单到只需要一条语句,这个时候我们就可以使用lambda表达式构造一个匿名函数对象,lambda表达式返回的也是一个函数对象,可以看到代码如下:

[python] view plain copy

  1. g=lambda x,y:x*y;
  2. print(g)

如上我们通过lambda表达式构造了一个匿名函数对象并打印它,打印结果如下:

       
       通过打印结果可以看到,function指的是这是一个函数,是通过lambda表达式构造出来的,后面是这个函数对象所在的内存地址。
2.lambda表达式应用案例
  接下来我们举一个例子,来更好的来了解lambda表达式。比如一个程序例子求整数n的阶乘,我们先来了解下之前惯用的方法,使用递归函数的这种方法代码如下:

[python] view plain copy

  1. def f(n):
  2.     if n==0:
  3.         return 1
  4.     else:
  5.         return n*f(n-1)
  6. print(f(5))

代码的打印结果如下:

   
其实递归的过程就是一个先入栈,后出栈的过程,栈这种数据结构的特点就是先进后出,我们可以看下面这个图来了解这种递归过程,图解如下:
   
   如上图所示,fun(5)=5*fun(4),但是这个时候并不知道fun(4)是多少,fun(5)先入栈,fun(4)调用函数,fun(4)=4*fun(3),这个时候需要求fun(3),fun(3)先入栈,fun(3)=3*fun(2),又要求fun(2),fun(2)入栈,fun(2)=2*fun(1),fun(1)=1*fun(0),紧接着fun(1),fun(0)依次入栈,此时从栈底到栈顶依次是fun(5),fun(4),fun(3),fun(2),fun(1),fun(0).
   当n=0时,fun(0)=1,fun(0)出栈;fun(1)=1*fun(0),fun(1)=1,fun(1)出栈;fun(2)=2*fun(1),fun(2)=2,fun(2)出栈;fun(3)=3*fun(2),fun(3)=6,fun(3)出栈;fun(4)=4*fun(3),fun(4)=24,fun(4)出栈;fun(5)=5*fun(4),fun(5)=120,fun(5)
出栈。最后fun(5)=120,打完收工。出栈次序为fun(0),fun(1),fun(2),fun(3),fun(4),fun(5)。
   这种不断的递归调用有两个缺点,一是需要不断入栈出栈,很是耗费内存,而且即使现在的内存优化机制有多么的好,如果让程序员去编写代码递归调用函数也是很耗脑力的。
   下面我们用lambda表达式来解决这个n的阶乘问题,代码如下:

[python] view plain copy

  1. from functools import reduce
  2. l={1,2,3,4,5}
  3. f=lambda x,y:x*y
  4. result=reduce(f,l)
  5. print(result)

代码的运行结果与上图是一样的,我们主要讲解下lambda表达式起到的作用与reduce函数的功能.

   首先我们定义一个序列l,其中l其实就是求n的阶乘需要用到的数,这里我们拿5的阶乘来举例,f是lambda表达式返回的函数对象,这个函数有两个参数x和y,函数的返回值就是x和y的乘积。
   然后,我们使用一个叫做reduce的函数,这个函数的功能就是,把序列l中的值依次取出来,作为f的实参并调用函数f,期间函数f的返回结果,也会作为实参与序列l的元素一起作为实参,调用函数f,最后直到l的元素全部用完,这么说可能不好理解,没关系,我们用下面的详细步骤可以很清楚的了解整个过程.如下:
  (1)l前2个元素作为实参,调用f,f(1,2)=2,返回结果2
  (2)返回结果2与l中的第3个元素作为实参,调用f,f(2,3)=6,返回6
  (3)返回结果6与l中的第4个元素作为实参,调用f,f(6,4)=24,返回24
  (4)返回结果24与l中的第5个元素作为实参,调用f,f(24,5)=120,返回120
  (5)最后l中没有元素,最终返回结果120,result=120,结束
  可以看到,在求n得阶乘过程中,我们把其中最简单的乘操作抽调出来,并用lambda来实现这个简单的操作,其他具体如何乘的过程,我们都交给了Python中预定义的函数reduce,编程简单可行,可读性强,可以说比起递归节省了不少脑力。
3.Switch语句的实现
      相信大家在学习C语言时都学过switch语句,不过Python中并没有switch语句,使用switch语句,需要用字典来实现它的结构,试想一下如果我们在编程时不使用switch语句,就只能使用if...elif...else这种判断结构来进行判断筛选,直到条件符合,执行需要执行的代码块,下面我们使用这种if...elif...else结构来实现switch结构,代码如下:

[python] view plain copy

  1. def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y
  9. def operator(o,x,y):
  10.     if o=='+':
  11.         print(add(x,y))
  12.     elif o=='-':
  13.         print(subtract(x,y))
  14.     elif o=='*':
  15.         print(mul(x,y))
  16.     elif o=='/':
  17.         print(divide(x,y))
  18.     else:
  19.         pass
  20. operator('/'52)

如上代码所示,我们实现了一个简单的计算器程序,程序的主要功能是计算两个数的加减乘除运算,4个函数add(x,y),subtract(x,y),mul(x,y),divide(x,y)分别实现加减乘除运算,函数operator(o,x,y)是使用if...elif...else结构实现switch语句,通过多级判断用户运算符,调用相应的函数,实现简单的计算器功能.

    最后,operator('/',5,2),调用计算器程序,实现5/2。打印结果如下:
    
       这种判断结构实现switch语句虽然可行,但是其缺点也不可避免.主要有两点,一是代码看起来并不简洁明了,结构混乱,可读性也比较差;二是程序可能需要进行多次判断,才能确定相应运算操作,比如operator('/',5,2),需要进行4次判断才能确定调用函数divide(x,y),这种判断结构是很耗费内存的。
      下面我们来使用字典来实现switch语句。字典元素都是键值对,那么如何确定字典元素的键和值呢?先看如下代码:

[python] view plain copy

  1. def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y
  9. print(add)
  10. print(subtract)
  11. print(mul)
  12. print(divide)

代码运行结果如下:

        
       可以看出,打印每个函数名,结果打印出的是一个个的函数对象,function代表一个函数,后面是函数名,以及这个函数对象在内存中的地址,为什么说是一个个函数对象呢?因为通过打印结果可以看出其在内存空间中的地址,既然内存为他分配了空间,说明他是内存中的实例,即对象。
       既然我们通过函数名可以得到函数对象,那我们用字典实现switch语句,初始化字典的键值对可以这样编写代码,代码如下:

[python] view plain copy

  1. operator={'+':add,'-':subtract,'/':divide,'*':mul}
  2. print(operator['+'](5,2))
  3. print(add(5,2))

如上代码所示,我们初始化字典时,把运算符作为字典的键,而函数对象作为字典的值,这样我们就可以通过字典的键,也就是运算符,获取到相应的函数对象,并调用这个函数对象,比如operator['+'],我们获取到了函数对象add,即operator['+']==add,而通过函数对象调用函数时,add(5,2)与operator['+'](5,2)是等价的,打印结果如下:

       
       在了解了字典在实现switch语句时如何初始化字典,下面我们就完完整整的实现这个计算器程序,代码如下:

[python] view plain copy

  1. def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y
  9. operator={'+':add,'-':subtract,'/':divide,'*':mul}
  10. def fun(o,x,y):
  11.     print(operator.get(o)(x,y))
  12. fun("/",5,2)

我们定义了一个函数fun(o,x,y),形参o为运算符,x和y为操作数,operator.get(o)(x,y),就是通过运算符获取字典里初始化好的函数对象,并调用函数实现运算,这样就实现了switch语句,避免了之前if...elif...else结构需要多重判断耗费内存的问题,真正实现一步到位,并且把数据部分与运算部分分割开来,代码的可读性更强。

       代码的运行结果如下:
       
 
      最后,大家看我的博客可能会觉得有些地方说的过分的细,甚至有些啰嗦,其实我的本意是在前期我们一同把Python的基础打好,这样以后我们学习一些框架就会得心应手,比如TensorFlow和caffe这些数据分析和处理的框架。其实无论学习Python或者这些框架,我们最终的目的都是要实现算法的思想,比如机器学习算法或者深度学习模型,"工欲善其事必先利其器",打好这些编程基础可以让我们在后面学习算法时,只注重算法本身的思想,而不用再把精力耗费在编程上,毕竟仰望星空前需要脚踏实地。
      下一节,我们将会介绍内建函数,敬请期待。
相关文章
|
23天前
|
Python 容器
Python学习的自我理解和想法(9)
这是我在B站跟随千锋教育学习Python的第9天,主要学习了赋值、浅拷贝和深拷贝的概念及其底层逻辑。由于开学时间紧张,内容较为简略,但希望能帮助理解这些重要概念。赋值是创建引用,浅拷贝创建新容器但元素仍引用原对象,深拷贝则创建完全独立的新对象。希望对大家有所帮助,欢迎讨论。
|
5天前
|
数据可视化 数据挖掘 大数据
1.1 学习Python操作Excel的必要性
学习Python操作Excel在当今数据驱动的商业环境中至关重要。Python能处理大规模数据集,突破Excel行数限制;提供丰富的库实现复杂数据分析和自动化任务,显著提高效率。掌握这项技能不仅能提升个人能力,还能为企业带来价值,减少人为错误,提高决策效率。推荐从基础语法、Excel操作库开始学习,逐步进阶到数据可视化和自动化报表系统。通过实际项目巩固知识,关注新技术,为职业发展奠定坚实基础。
|
14天前
|
Python
Python学习的自我理解和想法(10)
这是我在千锋教育B站课程学习Python的第10天笔记,主要学习了函数的相关知识。内容包括函数的定义、组成、命名、参数分类(必须参数、关键字参数、默认参数、不定长参数)及调用注意事项。由于开学时间有限,记录较为简略,望谅解。通过学习,我理解了函数可以封装常用功能,简化代码并便于维护。若有不当之处,欢迎指正。
|
25天前
|
存储 索引 Python
Python学习的自我理解和想法(6)
这是我在B站千锋教育学习Python的第6天笔记,主要学习了字典的使用方法,包括字典的基本概念、访问、修改、添加、删除元素,以及获取字典信息、遍历字典和合并字典等内容。开学后时间有限,内容较为简略,敬请谅解。
|
29天前
|
存储 程序员 Python
Python学习的自我理解和想法(2)
今日学习Python第二天,重点掌握字符串操作。内容涵盖字符串介绍、切片、长度统计、子串计数、大小写转换及查找位置等。通过B站黑马程序员课程跟随老师实践,非原创代码,旨在巩固基础知识与技能。
|
28天前
|
程序员 Python
Python学习的自我理解和想法(3)
这是学习Python第三天的内容总结,主要围绕字符串操作展开,包括字符串的提取、分割、合并、替换、判断、编码及格式化输出等,通过B站黑马程序员课程跟随老师实践,非原创代码。
|
25天前
|
Python
Python学习的自我理解和想法(7)
学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码! 今天是学Python的第七天,学的内容是集合。开学了,时间不多,写得不多,见谅。
|
24天前
|
存储 安全 索引
Python学习的自我理解和想法(8)
这是我在B站千锋教育学习Python的第8天,主要内容是元组。元组是一种不可变的序列数据类型,用于存储一组有序的元素。本文介绍了元组的基本操作,包括创建、访问、合并、切片、遍历等,并总结了元组的主要特点,如不可变性、有序性和可作为字典的键。由于开学时间紧张,内容较为简略,望见谅。
|
25天前
|
存储 索引 Python
Python学习的自我理解和想法(4)
今天是学习Python的第四天,主要学习了列表。列表是一种可变序列类型,可以存储任意类型的元素,支持索引和切片操作,并且有丰富的内置方法。主要内容包括列表的入门、关键要点、遍历、合并、判断元素是否存在、切片、添加和删除元素等。通过这些知识点,可以更好地理解和应用列表这一强大的数据结构。
|
25天前
|
索引 Python
Python学习的自我理解和想法(5)
这是我在B站千锋教育学习Python的第五天笔记,主要内容包括列表的操作,如排序(`sort()`、``sorted()``)、翻转(`reverse()`)、获取长度(`len()`)、最大最小值(`max()`、``min()``)、索引(`index()`)、嵌套列表和列表生成(`range`、列表生成式)。通过这些操作,可以更高效地处理数据。希望对大家有所帮助!
下一篇
开通oss服务