我正在搞乱lambda函数,我理解我能用简单的方式做些什么,但是当我尝试更先进的东西时,我遇到了错误,我不明白为什么。
如果你能告诉我哪里出错了,那就是我正在尝试的事情。
import math
C = lambda n,k: math.factorial(n)/(math.factorial(k))(math.factorial(n-k))
print C(10,5)
我应该注意到我在尝试在Codepad上运行代码时遇到了错误。我无法访问空闲。
答案 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