0

我的代码

import sys

number=int(sys.argv[1])

if number == 0
    fact=1
else
    fact=number
for (x=1; x<number; x++)
    fact*=x;             // mistake probably here

print fact

我得到错误

File "factorial.py", line 5
    if number == 0
                 ^
SyntaxError: invalid syntax

如何在 Python 中创建阶乘函数?

4

6 回答 6

12

您的错误所在的行应为

if number == 0:

注意末尾的冒号。

此外,您需要在 else 和 for 之后添加相同的冒号。冒号的工作方式与其他语言中的 {} 类似。

最后,这不是 Python 中 for 循环的工作方式。您要使用该列表的代码是

for x in range(1,number):

如果你把它放在 C 风格的语言中,它会产生与你所写内容相同的效果。

编辑:糟糕,我给出的 for 循环是错误的,它应该包含 0。我更新了代码来纠正这个问题。

于 2009-06-24T22:38:44.143 回答
9

我了解您可能出于教育原因尝试自己实现此功能。

但是,如果没有,我建议使用math模块内置的阶乘函数(注意:需要 python 2.6 或更高版本):

>>> import math
>>> math.factorial(5)
120

这个模块是用 C 语言编写的,因此,它比用 python 编写要快得多。(尽管,如果您不计算大型阶乘,那么无论哪种方式都不会太慢)。

于 2009-06-25T01:25:10.313 回答
8

这是您的代码,已修复并可以正常工作:

import sys
number = int(sys.argv[1])
fact = 1
for x in range(1, number+1):
    fact *= x

print fact

(对于不知道的人来说,阶乘为零是一 - 我必须查一下。8-)

if在, else,for等之后需要冒号, forPython 中的工作方式与 C 不同。

于 2009-06-24T22:40:43.813 回答
3

Mark Rushakoff 的 fact(n) 函数如此高效的原因是他错过了 reduce() 函数。因此,它实际上从未进行过计算。

更正它的内容(我明白了):

import operator, timeit, math
#
def fact1(n):  return reduce(lambda x,y: x*y,  range(1,n+1),1)
def fact1x(n): return reduce(lambda x,y: x*y, xrange(1,n+1),1)
def fact2(n):  return reduce(operator.mul   ,  range(1,n+1),1)
def fact2x(n): return reduce(operator.mul   , xrange(1,n+1),1)
#
def factorialtimer():
    for myfunc in [ "fact1", "fact1x", "fact2", "fact2x" ]:
        mytimer = timeit.Timer(myfunc+"(1500)", "from __main__ import "+myfunc)
        print("{0:15} : {1:2.6f}".format(myfunc, mytimer.timeit(number=1000)))

    mytimer = timeit.Timer("factorial(1500)", "from math import factorial")
    print("{0:15} : {1:2.6f}".format("math.factorial", mytimer.timeit(number=1000)))

1500!、1000x 的结果输出:

fact1           : 3.537624
fact1x          : 4.448408
fact2           : 4.390820
fact2x          : 4.333070
math.factorial  : 4.091470

是的,我已经检查过它们都产生相同的值!我不明白为什么 lambda xrange 比 lambda 范围差这么多。嗯。版本:Win32 上的 PythonWin 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)]。

嗯...在重新运行它时,我得到了更可信的东西

fact1           : 7.771696
fact1x          : 7.799568
fact2           : 7.056820
fact2x          : 7.247851
math.factorial  : 6.875827

在 cygwin 上的 Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01) [GCC 4.3.4 20090804 (release) 1] 上:

fact1           : 6.547000
fact1x          : 6.411000
fact2           : 6.068000
fact2x          : 6.246000
math.factorial  : 6.276000

一切都在喧嚣中,不是吗?

于 2010-10-07T12:44:34.690 回答
2

这是您几乎要求的功能阶乘:

>>> def fact(n): return reduce (lambda x,y: x*y, range(1,n+1))
... 
>>> fact(5)
120

它不适用于事实(0),但您可以担心超出范围的fact:)


Masi 曾询问函数式风格是否比 Richie 的实现更高效。根据我的快速基准测试(令我惊讶的是!)是的,我的速度更快。但是我们可以做几件事来改变。

首先,我们可以按照另一条评论中的建议替换为lambda x,y: x*yoperator.mulPython 的lambda运算符带来了不小的开销。其次,我们可以代替 xrange. 应该在线性空间中工作,根据需要返回数字,同时一次创建整个列表。(请注意,您几乎可以肯定必须使用过大的数字范围)rangexrangerangexrange

所以新的定义变成了:

>>> import operator
>>> def fact2(n): return reduce(operator.mul, xrange(1,n+1))
... 
>>> fact2(5)
120

令我惊讶的是,这实际上导致了性能下降。这是问答基准:

>>> def fact(n): return (lambda x,y: x*y, range(1,n+1))
... 
>>> t1 = Timer("fact(500)", "from __main__ import fact")
>>> print t1.timeit(number = 500)
0.00656795501709

>>> def fact2(n): return reduce(operator.mul, xrange(1,n+1))
...
>>> t2 = Timer("fact2(500)", "from __main__ import fact2")
>>> print t2.timeit(number = 500)
0.35856294632

>>> def fact3(n): return reduce(operator.mul, range(1,n+1))
... 
>>> t3 = Timer("fact3(500)", "from __main__ import fact3")
>>> print t3.timeit(number = 500)
0.354646205902

>>> def fact4(n): return reduce(lambda x,y: x*y, xrange(1,n+1))
... 
>>> t4 = Timer("fact4(500)", "from __main__ import fact4")
>>> print t4.timeit(number = 500)
0.479015111923

>>> def fact5(n):
...     x = 1
...     for i in range(1, n+1):
...             x *= i
...     return x
... 
>>> t5 = Timer("fact5(500)", "from __main__ import fact5")
>>> print t5.timeit(number = 500)
0.388549804688

这是我的 Python 版本,以防有人想交叉检查我的结果:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2
于 2009-06-24T22:51:24.087 回答
1

真的,最简单的选择是:

def factorial(n):
    x = n
    for j in range(1, n):
        x = j*x
    return x

是的,不知何故,它有效。

你怎么会没想到这一点?我不知道。

一个for循环和一个乘法器,真的简单是最好的方法,对吧?

编辑:哦,等等,我们正在为 CPU 效率最高的方式工作?哦……

于 2011-12-16T00:37:55.843 回答