Python安装时带有自己的函数库。阶乘函数 math.factorial()被包含在其数学模块中。数学模块是Python安装代码包的一部分。数学模块或函数,如阶乘、平方根、正弦和指数,可以在Python程序中使用。要使用它们,必须在调用数学函数之前使用导入命令,如下面的代码所示。
import math
print(math.factorial(4))
# the output is: 24 because 4 factorial is 24
import math 命令在代码执行过程中结合了Python库中的数学函数。
数学中的阶乘
在数学中,术语 阶乘 被赋予一个特定的表达式,它的结果是自然数的乘积按升序或降序排列。例如,1*2*3*4=24,被称为*"4阶乘",用4!*(带感叹号。
因此,1*2*3*4*5 就是5! 也可以写成5*4*3*2*1。一般来说,对于任意的(更大的)整数n,你可以写成n!=n*(n-1)*(n-2)*...*3*2*1。
因数有很多应用,特别是在概率和组合数学领域。组合学是关于计数,或安排事物的方法,或排列组合。举个非常简单的例子,一个人在书架上放4本书,有多少种可能?
_4_ _3_ _2_ _1_ 在左边的插图中,有4个书架位置。
你可以在第一个位置从左到右放置四本书中的任何一本。在第二个位置,你有3本书中的任何一本可以放在那里,以此类推。因此,摆放书籍的可能方式总数是4!=4*3*2*1=24。
这是一个有4个不同元素(书)的排列组合。一般来说,n个元素的互换数由n!=n*(n-1)*...*2*1给出。
一个更实际的例子是一个典型的国家彩票,彩票基本上有6组数字对或2位数的数字。每个数字由10个可能的数字组成,即0-9。有一个公式,可以用python数学阶乘函数来计算中奖概率。该公式为:。
其中n个元素的排列组合的数量每次取r。分母。 ***n!***这里指的是一对数字的使用范围。例如,如果从1到40挑选2位数,那么结果是。
所以,这个彩票的中奖概率是1/3818380。这说明,当使用阶乘数时,人们面对的是大数字。此外,这个案例包含一个分母,这就提出了为什么*0!*需要是1的重要性,因为不允许被零整除。买彩票是在浪费钱吗?
有趣的是,在离散数学中,组合概率与其他主题如图论、树、密码学和其他几个领域一起被涵盖。离散数学是出现在计算机科学课程中的一组重要课程。因此,阶乘数是编程的一个重要课题。可以说,在许多软件应用中,离散数学对程序员来说比微积分更需要掌握。
数学阶乘函数的替代品
在Python中,方法math.factorial ,可以用来计算前面提到的阶乘数。但像往常一样,你可以定义自己的阶乘函数来产生同样的结果。 下面的例子1和2定义了一个阶乘函数。例1包括一个关于阶乘数的非常重要的事实,即0!等于什么。在数学上,0!等于1,1!也等于1。也等于1。当你定义自己的函数时,包括这一点是很好的做法。下面的代码涵盖了0!和1!作为一个条件,并对任何一个条件都返回1;而下面例子2中的迭代方法并不涵盖0!。
因果律备选方案1:递归方法
import math
def fcto(n):
'''Factorial called fcto is defined'''
if n==0 or n==1 :
return 1
else :
return n * fcto(n-1)
# the rest of factorial expression, n(n-1)(n-2)...3(2)(1)
print(fcto(5))
# 120
在这个例子中,第6行是最棘手的,因为这是函数fcto 的递归部分。第13行的 [print()](https://blog.finxter.com/python-print/ "Python print()")第13行的命令首先调用以5为参数的函数,因此函数fcto(5) ,返回5 * fcto(4) ,然后在4上调用fcto ,返回4 * fcto(3) ,然后在3上调用fcto ,返回3 * fcto(2) ,以此类推,直到最后fcto(2-1) 为1,因此第4行被执行,返回1。
阶乘替代方案2:迭代方法
import math
def factorial(n):
fact = 1
for num in range(2, n+1):
fact *= num
return fact
print(factorial(4))
# 24
阶乘函数是用4调用的。在该函数的范围内,变量fact = 1 。然后,for循环迭代开始,num的值为2。 由于在第一次迭代中num 是2,那么就会返回2×1。在下一次迭代中num = 3 ,所以事实变量被分配为2×3,所以6被返回。到目前为止,2和6已经被返回。这就构成了前两个阶乘数,即1×2=2,或2!和1x2x3=6,或3!。在下一次迭代中,num 是4,所以事实被分配为6×4=24,也就是4!。这是最后一次迭代,因为范围的上限是n+1,或4+1=5。
5没有被使用,因为范围的上限命令没有被执行。
数学阶乘运行时的复杂性
阶乘数,n!,随着n的变大,数值增加得非常快,积的增长速度比快速增长的指数函数快得多,以10^x为例。
数学中常见函数的增长比较,一般表示为n!>> 10^x >> x^3 >> x^2 >> lnx,其中>>表示远大于大于。在计算机科学中,他们教的是大O记号。
重点是,当你设计算法时,使用*n!*的算法时,仔细进行运行时分析是很好的做法。
出于这个原因,你如何编写利用阶乘函数的程序,可能会在运行时间上产生重大差异。当计算大数时,如果可能的话,最好使用线性O(n)或O(log(n))。使用估计值甚至可能是可以接受的。例如,由于
等于
这是一个可以适用O(n log(n))的情况,但它是一个估计。这被称为*斯特林的近似值*,它给出了阶乘函数的近似值。然而,如果算法中涉及的数字足够大,对于合理的运行时间,这可能是一个可接受的解决方案。
Python是一种解释器类型的语言--在这种语言中不需要编译。这使得Python可以跨操作系统移植,并且易于使用。但是你为这些便利所付出的代价,例如,这些语言在计算上比较慢。例如,它们比Java或C++要慢。这也是为什么你必须小心实现math.factorial 函数的另一个原因。这里有3个例子可以说明运行时的差异。这3个例子都在上面讨论过。这里比较了这些片段的迭代、递归和math.factorial 的运行时间。
例1:递归方法的计时为30!
import math
import time
start = time.time()
def fcto(n):
if n==0 or n==1:
return 1
else:
return n*fcto(n-1)
print(fcto(30))
stop = time.time()
print("\ntime elapsed for Recursive: " + str(stop-start), "\n")
的输出。
265252859812191058636308480000000
time elapsed for Recursive: 0.011820793151855469
例2: 迭代法的时间为30!
import math
import time
start = time.time()
def factorial(n):
fact = 1
for num in range(2, n + 1):
fact *= num
return fact
print(factorial(30))
stop = time.time()
print("\ntime elapsed for iterative: " + str(stop-start), "\n")
的输出。
265252859812191058636308480000000
time elapsed for iterative: 0.0
例3:用math.factorial函数计时30分钟!
import math
import time
start = time.time()
print(math.factorial(30))
stop = time.time()
print("\ntime elapsed for math.factorial: " + str(stop-start), "\n")
Output: 265252859812191058636308480000000
time elapsed for math.factorial: 3.1948089599609375e-05
输出。
265252859812191058636308480000000
time elapsed for Recursive: 0.011820793151855469
这些都是简单算法的小程序,但它们提供了一个运行时间差异的样本。这里并没有说哪个程序是最好的,因为在程序执行时,我的电脑上可能还有其他操作系统进程在后台运行。主要的一点是,对于复杂的算法来说,时间上的差异可能是很大的,因此需要仔细分析。虽然,在多次运行这3个程序后,我发现3个程序的执行时间差异是一致的。
Python math.factorial() 一文首次出现在Finxter上。