我刚开始学习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) 是什么意思?
有人可以解释吗?
谢谢
我刚开始学习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) 是什么意思?
有人可以解释吗?
谢谢
阶乘本身几乎与您预期的一样。您推断a
is... 阶乘函数。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 传递给自身的荒谬方法。
就是这么简单:
n=input()
print reduce(lambda x,y:x*y,range(1,n+1))
让我们像洋葱一样剥开这个衬里。
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
这有点令人困惑,因为它被写成一个令人困惑的单行:)
这个功能有两个难点。
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的阶乘。
我们可以使用下面的 lambda 表达式
fact = lambda n:1 if n==0 else n*fact(n-1)
print(fact(5)
>>> 120
递归 lambda 的广义定义如下
recursive_lambda = (lambda func: lambda *args: func(func, *args))
很好解释!只有一个小修复:如果 b > 1 NOT 如果 b > 0
结果相同,但逻辑上更正确,因为它正在执行一个不必要的附加循环(即使乘以 1)
Wikipedia => n!,是所有小于或等于 n 的正整数的乘积
如果您想使用 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) )
使用 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
有问题的代码:
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)
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)))))