您的位置:首页 > 编程语言 > Python开发

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

2018-01-10 19:22 701 查看

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

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

def f(x,y):
return x*y
g=lambda x,y:x*y
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表达式返回的也是一个函数对象,可以看到代码如下:

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

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


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

def f(n):
if n==0:
return 1
else:
return n*f(n-1)
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的阶乘问题,代码如下:

from functools import reduce
l={1,2,3,4,5}
f=lambda x,y:x*y
result=reduce(f,l)
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结构,代码如下:
     
def add(x,y):
return x+y
def subtract(x,y):
return x-y
def mul(x,y):
return x*y
def divide(x,y):

4000
return x/y
def operator(o,x,y):
if o=='+':
print(add(x,y))
elif o=='-':
print(subtract(x,y))
elif o=='*':
print(mul(x,y))
elif o=='/':
print(divide(x,y))
else:
pass
operator('/', 5, 2)

     如上代码所示,我们实现了一个简单的计算器程序,程序的主要功能是计算两个数的加减乘除运算,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语句。字典元素都是键值对,那么如何确定字典元素的键和值呢?先看如下代码:
      
def add(x,y):
return x+y
def subtract(x,y):
return x-y
def mul(x,y):
return x*y
def divide(x,y):
return x/y
print(add)
print(subtract)
print(mul)
print(divide)

        代码运行结果如下:
        


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

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

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


       在了解了字典在实现switch语句时如何初始化字典,下面我们就完完整整的实现这个计算器程序,代码如下:
          
def add(x,y):
return x+y
def subtract(x,y):
return x-y
def mul(x,y):
return x*y
def divide(x,y):
return x/y
operator={'+':add,'-':subtract,'/':divide,'*':mul}
def fun(o,x,y):
print(operator.get(o)(x,y))
fun("/",5,2)

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


         
      最后,大家看我的博客可能会觉得有些地方说的过分的细,甚至有些啰嗦,其实我的本意是在前期我们一同把Python的基础打好,这样以后我们学习一些框架就会得心应手,比如TensorFlow和caffe这些数据分析和处理的框架。其实无论学习Python或者这些框架,我们最终的目的都是要实现算法的思想,比如机器学习算法或者深度学习模型,"工欲善其事必先利其器",打好这些编程基础可以让我们在后面学习算法时,只注重算法本身的思想,而不用再把精力耗费在编程上,毕竟仰望星空前需要脚踏实地。
      下一节,我们将会介绍内建函数,敬请期待。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python 编程