【python学习笔记】如何使用lambda的Y组合子技巧编写无名函数

什么是 Y 组合子?

Y 组合子是一种高阶函数,它允许一个函数能够调用自身,即使这个函数本身没有名字。通常,递归函数需要通过引用自身来递归,但是 Y 组合子通过一种特殊的结构让匿名函数也可以递归。

Y 组合子的原理

在 lambda 表达式中,没有直接的变量赋值和函数定义(如 def 或者 let)。Y 组合子的核心思想是通过一个自调用的高阶函数,让函数在没有名字的情况下自己调用自己。

Y 组合子的经典定义

Y = λf.(λx.f(x x))(λx.f(x x))
递归构造器:λf.(λx.f(x x))
  • lambda f 是一个高阶函数,接受一个函数 f 作为参数。
  • lambda x: f(x, x) 是一个返回递归函数的函数。这种构造允许我们将 f 传递给自身,从而实现递归调用。
递归主体:(λx.f(x x))
一个简单例子:
def num_eights(n):
"""返回n中有几个8

>>> num_eights(3)
0
>>> num_eights(8888)
4
"""
    if n  == 0:
        return 0
    elif n % 10 == 8:
        return 1 + num_eights(n // 10) 
    else:
        return num_eights(n // 10)

用Y组合子的方式使它变成无名函数:

"""
>>> num_eights(3)
0
>>> num_eights(8888)
4
"""
#                     0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10)
num_eights = (lambda f: (lambda x: f(f,x)))                                                                 (lambda f, x: 0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10))
#或者这样写
num_eights = (lambda f: lambda x: 0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10))  (lambda f, x: 0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10))    
  

这样我们可以看出:

(lambda x: f(f,x))
==
lambda x: 0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10))
其中
f(f,x)
==
0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10))
  • 外层的 (lambda f: lambda x: f(f, x)) 是 Y 组合子的构造器,它允许我们将 f 作为参数传递给自身,实现递归。
  • 内层的 lambda f, x: 0 if x == 0 else (1 + f(f, x // 10)) if x % 10 == 8 else f(f, x // 10) 是实际的递归函数体,它定义了如何处理递归逻辑。

关于 f 

  • λx: f(f, x) 中,f 是外部 lambda f 传递进来的函数。
  • f 代表的是 λf, x: ... 这个函数。
  • 因此,λx: f(f, x) 实际上是定义了如何调用 f 这个函数,其中 f 作为自身的递归调用。

具体解释

  1. 外部 lambda 实际上是将 λf, x: ... 作为参数传递进来,使得 f 可以在递归时使用。
  2. 内部 lambda 通过 f(f, x) 调用外部函数,并且 f 是递归的函数定义。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值