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

(知らなかった人のために、因数ゼロは 1 です。調べる必要がありました。8-)

, , などの後にはコロンが必要で、Python でのif動作はC とは異なります。elseforfor

于 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

はい、すべて同じ値になることを確認しました。ラムダ xrange がラムダ範囲よりもはるかに悪い理由がわかりません。うーん。バージョン: PythonWin 2.6.2 (r262:71605、2009 年 4 月 14 日、22:40:02) [MSC v.1500 32 ビット (Intel)] (win32)。

うーん...再実行すると、より信頼できるものが得られます

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

Python 2.6.5 (r265:79063、2010 年 6 月 12 日、17:07:01) [GCC 4.3.4 20090804 (リリース) 1] cygwin:

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*y置き換えることができます。operator.mulPython のlambda演算子には、かなりのオーバーヘッドが伴います。第二に、 を代用できxrangeますrange。 リスト全体を一度に作成しxrangeながら、線形空間で動作し、必要に応じて数値を返す必要があります。range(その場合、ほとんどxrangeの場合、過度に大きな範囲の数値に使用する必要があることに注意してください)

したがって、新しい定義は次のようになります。

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

驚いたことに、これにより実際にパフォーマンスが低下しました。Q&D ベンチマークは次のとおりです。

>>> 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 に答える