为什么我使用Lambda函数出错?

时间:2012-10-28 01:13:23

标签: python lambda

我正在搞乱lambda函数,我理解我能用简单的方式做些什么,但是当我尝试更先进的东西时,我遇到了错误,我不明白为什么。

如果你能告诉我哪里出错了,那就是我正在尝试的事情。

import math

C = lambda n,k: math.factorial(n)/(math.factorial(k))(math.factorial(n-k))

print C(10,5)

我应该注意到我在尝试在Codepad上运行代码时遇到了错误。我无法访问空闲。

3 个答案:

答案 0 :(得分:3)

试试这个:

from math import factorial
from __future__ import division

C = lambda n, k : factorial(n) / factorial(k) * factorial(n-k)

print C(10,5)
> 3628800.0

你错过了一个*,并且该分区也可能会考虑小数,因此旧的除法运算符/将不会这样做。这就是我导入新的/运算符的原因,该运算符执行十进制除法。

<强>更新

好吧,毕竟它似乎是Codepad的错 - 它在Python 2.6中添加了supports Python 2.5.1和factorial。只需实现自己的阶乘函数并完成它,或者甚至更好地开始使用真正的Python解释器。

def factorial(n):
    fac = 1
    for i in xrange(1, n+1):
        fac *= i
    return fac

答案 1 :(得分:1)

我认为你在第二个2因子条款之间缺少*。您收到错误是因为您尝试运行(math.factorial(k))(math.factorial(n-k)),这会变成类似10(math.factorial(n-k)的内容,这没有任何意义。

答案 2 :(得分:1)

据推测,您希望计算的值是“n-choose-k”,即一次取k个n个事物的组合数。其公式为n!/(k! * (n-k)!)。如果您的计算中添加了缺失的*,则会生成n!/k! * (n-k)!,等于(n!/k!)*(n-k)!。 (注意,k!均分n!。)例如,当n = 10且k = 5时,C(10,5)应为3628800 /(120 * 120)= 252,但是你的计算会给出3628800/120 * 120 = 3628800,这是不正确的14400倍。

您当然可以修复括号:

>>> C = lambda n,k: math.factorial(n)/(math.factorial(k)*math.factorial(n-k))
>>> C(10,5)
252

但请注意,如果math.factorial(j)需要j-1次乘法来计算,则C(n,k)取n-1 + k-1 + nk-1 + 1 = 2 * n-2次乘法一个师。这是必要的乘法运算的四倍。下面显示的代码使用j乘法和j除法,其中j是k和n-k中的较小者,因此j最多为n / 2。在某些机器上,除法比乘法慢得多,但在大多数机器上,j乘法和j除法运行速度比2 * n-2乘法和一个除法要快得多。

更重要的是,C(n,k)远小于n!。当n超过20时,通过n!/(k!*(n-k)!)公式计算需要超过64位精度。例如,C(21,1)返回值21L。相比之下,下面的代码计算D(61,30)= 232714176627630544之前需要超过64位来计算D(62,31)= 465428353255261088L。 (我将函数命名为“D”而不是“C”,以避免名称冲突。)

对于大型快速机器上的小型计算,额外的乘法和额外的精度要求并不重要。但是,对于小型机器上的大型计算,它们变得很重要。

简而言之,D()中的乘法和除法的顺序保持最小的最大中间值。最大值出现在for循环的最后一个传递中。另请注意,在for循环中,i始终是c * j的精确除数,并且不会发生截断。这是用于计算“n-choose-k”的相当标准的算法。

def D(n, k):
    c, j, k = 1, n, min(k,n-k)
    for i in range(1,k+1):
        c, j = c*j/i, j-1
    return c

口译员的结果:

>>> D(10,5)
252
>>> D(61,30)
232714176627630544
>>> D(62,31)
465428353255261088L