我在python中的factorial代码出了什么问题

dan*_*ous 3 python python-2.7

我有以下代码用于计算python中数字的阶乘.但我无法理解为什么我得到的答案是1.可以有人纠正我的代码.我想在不使用递归的情况下计算阶乘.

def factorial (n):
        result =1 
        num = n
        while n<1:
            result = result * num
            num = num -1
        return result

    factorial(5)
    1
Run Code Online (Sandbox Code Playgroud)

Fre*_*abe 6

其他人指出你的代码有什么问题,但我想指出一个factorial函数真正适用于更多功能(如:函数式编程)解决方案; 这避免了while完全获得循环条件的问题,因为你根本没有任何循环.洞察力是阶乘n是产品1..n,并且使用Python的reduce功能可以非常容易地定义产品.为了避免失去性能,这是我的Python 2.7解释器为您的(固定)代码提供的:

python -m timeit -s "import original" "original.factorial(10)"
1000000 loops, best of 3: 1.22 usec per loop
Run Code Online (Sandbox Code Playgroud)

可以使用更具说明性的更短版本(单行):

def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
Run Code Online (Sandbox Code Playgroud)

......唉,它慢了:

python -m timeit -s "import func1" "func1.factorial(10)"
1000000 loops, best of 3: 1.98 usec per loop
Run Code Online (Sandbox Code Playgroud)

然而,这可以通过使用来解决xrange,而不是rangeoperator.mul,而不是一个自定义的λ:

import operator

def factorial(n):
    return reduce(operator.mul, xrange(1, n+1))
Run Code Online (Sandbox Code Playgroud)

而对我来说,这比原始代码更快:

python -m timeit -s "import func2" "func2.factorial(10)"
1000000 loops, best of 3: 1.14 usec per loop
Run Code Online (Sandbox Code Playgroud)

就个人而言,我会把reduce这个代码分解得更清楚(以牺牲一小部分性能为代价):

import operator

def product(it):
    return reduce(operator.mul, it)

def factorial(n):
    return product(xrange(1, n+1))
Run Code Online (Sandbox Code Playgroud)

我喜欢这个版本的快速和明确:因子被定义为范围[1..n + 1 [(即n + 1除外)的乘积.如果您尝试计算较大数字的阶乘,性能差异会变得更明显:

python -m timeit -s "import original" "original.factorial(30)"
100000 loops, best of 3: 5.25 usec per loop
Run Code Online (Sandbox Code Playgroud)

python -m timeit -s "import func3" "func3.factorial(30)"
100000 loops, best of 3: 3.96 usec per loop
Run Code Online (Sandbox Code Playgroud)

  • @Pureferret [链接到外部内容中断](http://meta.stackexchange.com/questions/80621/links-to-external-content-how-do-we-mitigate-degradation-of-so-as-external-链接)和(作为特定的答案引用)"SO的主要目标之一是提供一个全面的Q&A存储库(而不仅仅是一个问答论坛)".如果接受的答案的作者会用我写的内容扩展他的文本,我会很高兴,但只要情况不是这样,添加另一个后退的答案是公平的妥协.如果它让你开心,我还可以添加一个"将`n <1`改为`num> 1`." ;-) (3认同)