深入解析Python中的lambda表达式的用法


Posted in Python onAugust 28, 2015

普通的数学运算用这个纯抽象的符号演算来定义,计算结果只能在脑子里存在。所以写了点代码,来验证文章中介绍的演算规则。

我们来验证文章里介绍的自然数及自然数运算规则。说到自然数,今天还百度了一下,据度娘说,1993年后国家规定0是属于自然数。先定义自然数及自然数的运算规则:

用lambda表达式定义自然数(邱齐数)

0 := λf.λx.x
1 := λf.λx.f x
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))
...

上面定义直观的意思就是数字n, 是f(x)的n阶函数。1就是f(x), 2就是f(f(x))....,严格来说,这样表述并不准确。其实每个邱奇数都是一个二阶函数,它有两个变量f和x。用二元命名函数来表达就是:

0 -> num0(f,x)=x
1 -> num1(f, x)=f(x)
2 -> num2(f,x)=f(f(x))
3 -> num3(f,x)=f(f(f(x)))
...

 其中参数f是一个函数。这一段有点绕,但是不能理解这个,对后面的lambda演算理解会比较困难。

首先用递归法,定义邱齐数(自然数)

0是自然数,  度娘说1993年后,国家规定0是属于自然数。

每个自然数,都有一个后续。

用代码表达就是:

NUM0=lambda f: lambda x:x
SUCC=lambda n: lambda f: lambda x: f(n(f)(x))

后面则是定义运算符,包括加法,乘法,减法和幂。维基文章里没有介绍除法,估摸着除法定义比较复杂,一时讲不清楚。那我们也不验证了。

################################################
#define number calculus rules
################################################
 
#define Church numeral inductively.
#0 := λf.λx.x
#1 := λf.λx.f x
#2 := λf.λx.f (f x)
#3 := λf.λx.f (f (f x))
#...
NUM0=lambda f: lambda x:x
SUCC=lambda n: lambda f: lambda x: f(n(f)(x))
 
#define Operator
PLUS=lambda m: lambda n: m(SUCC)(n)
MULT= lambda m: lambda n: m(PLUS(n))(NUM0)
#define predecessor to obtain the previous number.
PRED= lambda n: lambda f: lambda x: n(lambda g: lambda h: h(g(f)))(lambda u:x)(lambda u:u)
SUB=lambda m: lambda n: n(PRED)(m)
POW=lambda b: lambda e: e(b)

定义完了什么是自然数和自然数的运算子。那么自然数的运算,就可以用lambda演算的方式计算了。

问题是上面的定义都是抽象的符号演算,我们需要有一个编码器来把上面的抽象的Church numeral符号编码成可以人来阅读的形式,还需把人输入的数字解码成抽象符号。

################################################
#create encoder to input/output Church numeral
################################################
 
class LambdaEncoding:
  @staticmethod
  def encoding(exp,encoder):
    return encoder().encoding(exp)
  @staticmethod
  def decoding(s, decoder):
    return decoder().decoding(s)
   
class NumEncoder:
  def encoding(self,num):
    f=lambda x:x+1
    return str(num(f)(0))
  def decoding(self,s):
    n=int(s)
    num=NUM0
    for i in range(n):
      num=SUCC(num)
    return num

嗯,有了编码器,就可以方便的来验证了。

################################################
#calculus demo
################################################
print("demo number calculus.\n"
   "don't input large number,"
   "it will cause to exceed maximum recursion depth!\n")
 
n1=input('input a number: ')
n2=input('input anohter number: ')
#decode string to Church numeral
num1=LambdaEncoding.decoding(n1,NumEncoder)
num2=LambdaEncoding.decoding(n2,NumEncoder)
   
#add
result=PLUS(num1)(num2)
 
print('{0} + {1} = {2}'.format(
  n1,
  n2,
  LambdaEncoding.encoding(result, NumEncoder)))
 
#mult
result=MULT(num1)(num2)
print('{0} X {1} = {2}'.format(
  n1,
  n2,
  LambdaEncoding.encoding(result, NumEncoder)))
#sub
result=SUB(num1)(num2)
print('{0} - {1} = {2}'.format(
  n1,
  n2,
  LambdaEncoding.encoding(result, NumEncoder)))
 
#POW
result=POW(num1)(num2)
print('{0} ^ {1} = {2}'.format(
  n1,
  n2,
  LambdaEncoding.encoding(result, NumEncoder)))

测试结果如下:

>>> 
demo number calculus.
don't input large number,it will cause to exceed maximum recursion depth!
 
input a number: 4
input anohter number: 3
4 + 3 = 7
4 X 3 = 12
4 - 3 = 1
4 ^ 3 = 64
>>>

神奇吧。

lambda和def的区别
python lambda是在python中使用lambda来创建匿名函数,而用def创建的方法是有名称的,除了从表面上的方法名不一样外,python lambda还有哪些和def不一样呢?
1 python lambda会创建一个函数对象,但不会把这个函数对象赋给一个标识符,而def则会把函数对象赋值给一个变量。
2 python lambda它只是一个表达式,而def则是一个语句。
下面是python lambda的格式,看起来好精简阿。

lambda x: print x

如果你在python 列表解析里用到python lambda,我感觉意义不是很大,因为python lambda它会创建一个函数对象,但马上又给丢弃了,因为你没有使用它的返回值,即那个函数对象。也正是由于lambda只是一个表达式,它可以直接作为python 列表或python 字典的成员,比如:

info = [lamba a: a**3, lambda b: b**3]

在这个地方没有办法用def语句直接代替。因为def是语句,不是表达式不能嵌套在里面,lambda表达式在“:”后只能有一个表达式。也就是说,在def中,用return可以返回的也可以放在lambda后面,不能用return返回的也不能定义在python lambda后面。因此,像if或for或print这种语句就不能用于lambda中,lambda一般只用来定义简单的函数。
下面举几个python lambda的例子吧
1单个参数的:

g = lambda x:x*2
print g(3)

结果是6
多个参数的:

m = lambda x,y,z: (x-y)*z
print m(3,1,2)

结果是4

Python 相关文章推荐
Python用Bottle轻量级框架进行Web开发
Jun 08 Python
Python 获得13位unix时间戳的方法
Oct 20 Python
Python 12306抢火车票脚本 Python京东抢手机脚本
Feb 06 Python
python二维列表一维列表的互相转换实例
Jul 02 Python
解决使用PyCharm时无法启动控制台的问题
Jan 19 Python
django的ORM模型的实现原理
Mar 04 Python
Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答
Aug 13 Python
Python实现链表反转的方法分析【迭代法与递归法】
Feb 22 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
Feb 29 Python
python实现处理mysql结果输出方式
Apr 09 Python
Python通过Pillow实现图片对比
Apr 29 Python
Python流程控制语句的深入讲解
Jun 15 Python
两个使用Python脚本操作文件的小示例分享
Aug 27 #Python
简介二分查找算法与相关的Python实现示例
Aug 26 #Python
使用Python的Bottle框架写一个简单的服务接口的示例
Aug 25 #Python
栈和队列数据结构的基本概念及其相关的Python实现
Aug 24 #Python
如何使用七牛Python SDK写一个同步脚本及使用教程
Aug 23 #Python
Python中for循环和while循环的基本使用方法
Aug 21 #Python
Python中条件判断语句的简单使用方法
Aug 21 #Python
You might like
linux命令之调试工具strace的深入分析
2013/06/03 PHP
如何把php5.3版本升级到php5.4或者php5.5
2015/07/31 PHP
PHP中spl_autoload_register()函数用法实例详解
2016/07/18 PHP
PHP实现将MySQL重复ID二维数组重组为三维数组的方法
2016/08/01 PHP
thinkphp Apache配置重启Apache1 restart 出错解决办法
2017/02/15 PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
2019/09/02 PHP
jQuery之过滤元素操作小结
2013/11/30 Javascript
详解JavaScript的变量和数据类型
2015/11/27 Javascript
分享使用AngularJS创建应用的5个框架
2015/12/05 Javascript
JavaScript计算器网页版实现代码分享
2016/07/15 Javascript
javascript cookie用法基础教程(概念,设置,读取及删除)
2016/09/20 Javascript
JS中位置与大小的获取方法
2016/11/22 Javascript
基于jquery实现二级联动效果
2017/03/30 jQuery
AngularJS实现注册表单验证功能
2017/10/16 Javascript
Next.js实现react服务器端渲染的方法示例
2019/01/06 Javascript
jquery无缝图片轮播组件封装
2020/11/25 jQuery
[04:26]2014DOTA2国际邀请赛-Newbee顺利进入胜者组决赛 独家专访战神7
2014/07/19 DOTA
[51:15]完美世界DOTA2联赛PWL S2 PXG vs Magma 第一场 11.21
2020/11/24 DOTA
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
Python搜索引擎实现原理和方法
2017/11/27 Python
PyTorch之图像和Tensor填充的实例
2019/08/18 Python
python绘制彩虹图
2019/12/16 Python
python实现将列表中各个值快速赋值给多个变量
2020/04/02 Python
Python验证码截取识别代码实例
2020/05/16 Python
HTML5之WebGL 3D概述(下)—借助类库开发及框架介绍
2013/01/31 HTML / CSS
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
实习单位接收函模板
2014/01/10 职场文书
诚信的演讲稿范文
2014/05/12 职场文书
出差报告范文
2014/11/06 职场文书
2014年督导工作总结
2014/11/19 职场文书
平凡的世界读书笔记
2015/06/25 职场文书
文艺演出主持词
2015/07/01 职场文书
表彰大会新闻稿
2015/07/17 职场文书
2016年重阳节慰问信
2015/12/01 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
css中z-index: 0和z-index: auto的区别
2021/08/23 HTML / CSS