Python lambda函数计算一个数的阶乘

9

我刚开始学习Python。我遇到了lambda函数。在其中一个问题中,作者要求编写一行代码的lambda函数来计算一个数字的阶乘。

这是给出的解决方案:

num = 5
print (lambda b: (lambda a, b: a(a, b))(lambda a, b: b*a(a, b-1) if b > 0 else 1,b))(num)

我不理解这种奇怪的语法。a(a,b)是什么意思?

有人能解释一下吗?

谢谢


12
我有一个更好的:lambda b: math.factorial(b) - JBernardo
2
不要重新发明方形轮子。 - ShuklaSannidhya
11个回答

10

阶乘函数本身就像你预期的那样。你可以推断出 a 是... 阶乘函数,b 是实际参数。

<factorial> = lambda a, b: b*a(a, b-1) if b > 0 else 1

这一部分是阶乘的应用:

<factorial-application> = (lambda a, b: a(a, b))(<factorial>, b)

a 是阶乘函数本身。它把自身作为第一个参数,将求值点作为第二个参数。只要您不介意 a(a, b - 1) 而不是 a(b - 1),则可以将此推广到 recursive_lambda

recursive_lambda = (lambda func: lambda *args: func(func, *args))
print(recursive_lambda(lambda self, x: x * self(self, x - 1) if x > 0 else 1)(6))
# Or, using the function verbatim:
print(recursive_lambda(lambda a, b: b*a(a, b-1) if b > 0 else 1)(6))

所以我们有外部部分:

(lambda b: <factorial-application>)(num)

正如您所看到的,所有调用者只需通过评估点。


如果您确实想要一个递归 lambda 函数,您可以简单地给 lambda 函数命名

fact = lambda x: 1 if x == 0 else x * fact(x-1)

如果不行,你可以使用一个简单的帮助函数。你会注意到ret 是一个可以引用自身的lambda函数,而在之前的代码中没有任何lambda函数可以引用自身。

def recursive_lambda(func):
    def ret(*args):
        return func(ret, *args)
    return ret

print(recursive_lambda(lambda factorial, x: x * factorial(x - 1) if x > 1 else 1)(6))  # 720

两种方式都无需使用荒谬的方法将lambda传递给自身。


澄清一下:a 是被传递给它自己吗? - ApproachingDarknessFish
1
那是一个全新的扭曲层次。 - ApproachingDarknessFish
很抱歉回复这么晚。我理解了你所解释的内容。我几乎忘记了我没有回复。 - drcocoa

7
这很简单:
n=input()

print reduce(lambda x,y:x*y,range(1,n+1))

6

让我们像剥洋葱一样分解这个一行代码。

print (lambda b: (Y))(num)

我们正在创建一个匿名函数(关键字lambda意味着我们将输入一系列参数名称,然后是一个冒号,接着是使用这些参数的函数),然后将num传递给它以满足其一个参数。
   (lambda a, b: a(a, b))(X,b)

在 lambda 函数内部,我们定义了另一个 lambda 函数。将其称为 Y。这个函数接受两个参数 a 和 b。a 通过传入 a 和 b 被调用,因此 a 是一个可调用对象,它接受自身和另一个参数。

            (lambda a, b: b*a(a, b-1) if b > 0 else 1
            ,
            b)

这些是Y函数的参数。第一个参数是一个lambda函数,称其为X。我们可以看出X是阶乘函数,第二个参数将成为它的数字。

也就是说,如果我们回到Y函数,我们会调用:

X(X, b)

这将会执行

b*X(X, b-1) if b > 0 else 1

同时,它会调用自身,形成阶乘的递归部分。

并且从外部看,我们可以看到b是我们传入最外层lambda函数中的num。

num*X(X, b-1) if num > 0 else 1

由于它被写成一行令人困惑的代码,所以可能会让人感到困惑 :)


这是一场关于一行代码的在线比赛。我正在为此做准备。一开始感到有些困惑,但经过大量时间的投入,我认为我已经掌握了它。谢谢。 - drcocoa

2
我们可以使用以下lambda表达式。
     fact = lambda n:1 if n==0 else n*fact(n-1)
     print(fact(5)
     >>> 120

2

这个函数有两个难点。
1. lambda a, b: b*a(a, b-1) if b > 0 else 1
2. 接在1后面的那个“b”。

对于第一个难点,它不过是:

def f(a, b):
    if b > 0:
        b * a(a, b - 1)
    else:
        1

对于2,这是b

(lambda b: (lambda a, b: a(a, b))(lambda a, b: b*a(a, b-1) if b > 0 else 1,b))(num)
                                                                      (this one)

实际上是这样的 b:

(lambda b: (lambda a, b: a(a, b))(lambda a, b: b*a(a, b-1) if b > 0 else 1,b))(num)
   (this one)

原因是它不在第二个和第三个lambda的定义内,所以它引用了第一个b。

在我们应用num并剥离外部函数之后:

(lambda a, b: a(a, b))  (lambda a, b: b*a(a, b-1) if b > 0 else 1, num) 

这只是将函数应用到元组上,(lambda a, b: b*a(a, b-1) if b > 0 else 1, num)
我们将这个元组称为(f, num) (f的定义在上面) 将lambda a, b: a(a, b)应用于它,我们得到

f(f, num).

假设你的num是5。
根据f的定义,它首先计算为

5 * f(f, 4)  

然后转为:

5 * (4 * f(f, 3)) 

一直到底部

5 * (4 * (3 * (2 * (1 * f(f, 0)))))

f(f,0)的结果为1。

5 * (4 * (3 * (2 * (1 * 1))))

开始吧,5的阶乘。


0

递归lambda的一般定义如下:

recursive_lambda = (lambda func: lambda *args: func(func, *args))

0
非常好的解釋!只有一個小修正:如果 b > 1 而不是 b > 0
結果相同,但從邏輯上來看更正確,因為它執行了一個不必要的額外循環(即使乘以 1)
Wikipedia => n!,是所有小於或等於n的正整數的乘積。

0

使用Lambda函数查找阶乘的简单方法

fac = lambda x : x * fac(x-1) if x > 0 else 1

print(fac(5))

输出: 120

用户输入以查找阶乘

def fac():

    fac_num = int(input("Enter Number to find Factorial "))

    factorial = lambda f : f * factorial(f-1) if f > 0 else 1

    print(factorial(fac_num))

fac()

输入要查找阶乘的数字:5

120


0

相关代码:

lambda b : (lambda a, b : a(a, b)) (lambda a, b : b * a(a, b-1) if b > 0 else 1,  b)

为了更清晰,让我用f代替变量名a,用n代替变量名b
lambda n : (lambda f, n : f(f, n)) (lambda f, n : n * f(f, n-1) if n > 0 else 1,  n)

递归阶乘是一个会调用自身或应用于自身的函数,类似于 f(f)。 让我们将 Factorial(n) 设为 f(f,n) 并按以下方式计算:

def func(f, n):  # takes a function and a number, return a number.
        if n > 0 :
            return n * f(f, n-1)
        else :
            return 1

将上述的def func函数转换为lambda表达式:

func is     lambda f, n : n * f(f, n-1) if n > 0 else 1 

接下来需要将函数应用于自身和整数n。

回到最初的语句,Factorial(n)是f(f,n),或者当将函数func应用于f时,为f(func,n)。

def Factorial(n):  
    # return f (func, n)  # next, substitute f and func with their corresponding lambdas.
    return (lambda f, n : f(f, n))  (lambda f, n : n * f(f, n-1) if n > 0 else 1, n)

使用lambda代替def阶乘,整个代码如下:

lambda n : (lambda f, n : f(f, n)) (lambda f, n : n * f(f, n-1) if n > 0 else 1, n)

0
如果您想使用lambda表达式进行阶乘计算,则需要添加if else条件,例如:
if x==1: 
    return 1 
else 
    return x*function_name(x-1)

例如,fact 是我的 lambda 表达式:

fact(lambda x: 1 if x == 1 else x * fact(x-1))

这是递归的 if else 条件语句


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接