質問
マイコード
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で階乗関数を作成するにはどうすればよいですか
解決
修正および動作するコードを次に示します。
import sys
number = int(sys.argv[1])
fact = 1
for x in range(1, number+1):
fact *= x
print fact
(Factorialゼロは1です。知らなかった人にとっては-調べなければなりませんでした。8)
if
、 else
、 for
など、および for
の動作方法の後にコロンが必要ですPythonはCとは異なります。
他のヒント
エラーのある行を読む必要があります
if number == 0:
末尾のコロンに注意してください。
さらに、elseとforの後に同じコロンを追加する必要があります。コロンは、他の言語の{}と同様に機能します。
最後に、それはPythonのforループの動作ではありません。そのリストを使用するコードは次のようになります
for x in range(1,number):
Cスタイル言語で記述した場合、記述した内容と同じ効果があります。
編集:エラー、forループは間違っていました。0が含まれていたはずです。これを修正するためにコードを更新しました。
おそらく教育的な理由でこれを自分で実装しようとしていることを理解しています。
ただし、そうでない場合は、組み込みの階乗関数 math
モジュールを使用することをお勧めします(注:Python 2.6以降が必要です):
>>> import math
>>> math.factorial(5)
120
このモジュールはCで記述されているため、pythonで記述するよりもはるかに高速です。 (ただし、大きな階乗を計算していない場合は、どちらの方法でも遅すぎることはありません。)
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)[cygwinの[GCC 4.3.4 20090804(リリース)1]:
fact1 : 6.547000
fact1x : 6.411000
fact2 : 6.068000
fact2x : 6.246000
math.factorial : 6.276000
すべてが本当にノイズの中にありませんか?
これは機能的な階乗であり、あなたがほとんど求めていました:
>>> def fact(n): return reduce (lambda x,y: x*y, range(1,n+1))
...
>>> fact(5)
120
fact(0)では機能しませんが、 fact
の範囲外では心配することができます:)
Masiは、機能的なスタイルがRichieの実装よりも効率的かどうかを尋ねました。私の簡単なベンチマークによると(そして驚いたことに!)はい、私のほうが高速です。しかし、変更するためにできることがいくつかあります。
最初に、別のコメントで提案されているように、 lambda x、y:x * y
を operator.mul
に置き換えることができます。 Pythonの lambda
演算子には、ささいなオーバーヘッドはありません。次に、 range
の代わりに xrange
を使用できます。 xrange
は線形空間で動作し、必要に応じて数値を返しますが、 range
はリスト全体を一度に作成します。 (その場合、非常に大きな範囲の数値に対してはほぼ確実に xrange
を使用する必要があります)
したがって、新しい定義は次のようになります。
>>> import operator
>>> def fact2(n): return reduce(operator.mul, xrange(1,n+1))
...
>>> fact2(5)
120
驚いたことに、これにより実際にパフォーマンスが低下しました。 Q&amp; 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
本当に、最も簡単なオプションは次のとおりです:
def factorial(n):
x = n
for j in range(1, n):
x = j*x
return x
はい、どういうわけか機能します。
どうしてこれを考えられなかったの?わからない。
for for
ループと乗数、本当にシンプルなのが最善の方法ですよね?
編集:ああ、待ってください、私たちは最もCPU効率の良い方法で作業していますか?ああ.......