8

我刚开始学习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) 是什么意思?

有人可以解释吗?

谢谢

4

11 回答 11

8

阶乘本身几乎与您预期的一样。您推断ais... 阶乘函数。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是阶乘函数本身。它将自己作为第一个参数,将评估点作为第二个参数。recursive_lambda只要您不介意,这可以概括a(a, b - 1)a(b - 1)

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 传递给自身的荒谬方法。

于 2013-03-14T04:48:33.380 回答
7

就是这么简单:

n=input()

print reduce(lambda x,y:x*y,range(1,n+1))
于 2017-03-29T09:03:22.337 回答
6

让我们像洋葱一样剥开这个衬里。

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

我们正在创建一个匿名函数(关键字 lambda 表示我们将键入一系列参数名称,然后是一个冒号,然后是一个使用这些参数的函数),然后将其传递 num 以满足其一个参数。

   (lambda a, b: a(a, b))(X,b)

在 lambda 内部,我们定义了另一个 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

这有点令人困惑,因为它被写成一个令人困惑的单行:)

于 2013-03-14T04:52:27.190 回答
2

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

对于1,无非是:

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 是 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的阶乘。

于 2013-03-14T05:54:37.863 回答
2

我们可以使用下面的 lambda 表达式

     fact = lambda n:1 if n==0 else n*fact(n-1)
     print(fact(5)
     >>> 120
于 2016-02-04T09:38:18.717 回答
0

递归 lambda 的广义定义如下

recursive_lambda = (lambda func: lambda *args: func(func, *args))
于 2016-06-06T06:09:36.017 回答
0

很好解释!只有一个小修复:如果 b > 1 NOT 如果 b > 0

结果相同,但逻辑上更正确,因为它正在执行一个不必要的附加循环(即使乘以 1)

Wikipedia => n!,是所有小于或等于 n 的正整数的乘积

于 2017-02-02T19:28:13.173 回答
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 条件

于 2019-03-06T19:42:40.797 回答
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

于 2020-05-07T04:46:31.457 回答
0

有问题的代码:

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

为了更清楚,让我replace variable names a with f, and b with n

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

Recursive Factorial 是一个将调用自身或应用于自身的函数,例如 f(f)。让我们设置Factorial(n) to be 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 

func is then to be applied to itself along with integer n.

Back to beginning statement, Factorial(n) is f(f,n), or f(func,n) when func is applied into f.

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)

and using lambda instead of def Factorial, the whole thing becomes:

lambda n : (lambda f, n : f(f, n)) (lambda f, n : n * f(f, n-1) if n > 0 else 1, n)
于 2020-09-03T15:59:29.990 回答
-1
while True: 
    #It is this simple:
    from functools import reduce
    n=input('>>')
    n=int(n)
    if n==0:
        print('factorial: ',1)
    elif n<0:
        print('invalid input')
    else:
        print('factorial: ',(reduce(lambda x,y:x*y,list(range(1,n+1)))))
于 2020-05-13T12:13:32.440 回答