Frage

Mein Code

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

Ich erhalte den Fehler

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

Wie kann man eine Fakultäts-Funktion in Python machen?

War es hilfreich?

Lösung

Hier ist der Code, fest und arbeiten:

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

print fact

(Factorial Null ist einer, für alle, die nicht wissen, -. Ich hatte es nachzuschlagen 8 -)

Sie müssen Doppelpunkte nach if, else, for usw. und die Art und Weise for in Python arbeitet unterscheidet sich von C.

Andere Tipps

Die Zeile, die Ihre Fehler auf sollte, ist lesen

if number == 0:

Beachten Sie den Doppelpunkt am Ende.

Darüber hinaus müssen Sie den gleichen Doppelpunkt nach den anderen und dem für hinzuzufügen. Die Doppelpunkte funktionieren ähnlich wie {} in anderen Sprachen.

Schließlich, das ist nicht, wie für Schleifen in Python arbeiten. Der Code, den Sie diese Liste verwenden möchten, wäre

for x in range(1,number):

, die die gleiche Wirkung haben würde, was Sie geschrieben haben, wenn Sie, dass wie in C Sprache setzen.

EDIT:. Oops, die for-Schleife habe ich falsch war, wäre es aufgenommen hat 0. ich den Code aktualisiert, dies zu korrigieren

Ich verstehe, dass Sie wahrscheinlich versuchen, dies zu implementieren, sich aus pädagogischen Gründen.

Wenn jedoch nicht, empfehle ich mit dem math Module Einbau-Fakultäts-Funktion (Anmerkung: erfordert Python 2.6 oder höher):

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

Dieses Modul ist in C geschrieben, und als solche, es wird viel viel schneller, als es in Python zu schreiben. (Obwohl, wenn Sie nicht großes factorials Computing, wird es nicht wirklich so oder so zu langsam auch).

Der Grund Mark Rushakoff die Tatsache (n) Funktion so viel effizienter war, dass er vermisste-off der Verringerung () Funktion. So ist es nie tat tatsächlich die Berechnung.

Korrigierte es liest (und ich):

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)))

Resultierende Ausgabe für 1500 !, 1000x:

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

Und ja, ich habe überprüft sie alle den gleichen Wert ergeben! Ich kann nicht verstehen, warum das Lambda xrange so viel schlimmer als der Lambda-Bereich liegt. Hmmm. Ausführung: PythonWin 2.6.2 (R262: 71605, 14. April 2009, 22.40.02). [MSC v.1500 32 Bit (Intel)] auf win32

Hmm ... auf Wieder läuft es mir etwas glaubhafte

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

Und auf Python 2.6.5 (R265: 79063, 12. Juni 2010, 17.07.01) [GCC 4.3.4 20.090.804 (release) 1] auf Cygwin:

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

Alle in dem Lärm wirklich, nicht wahr?

Hier ist ein Funktions-faktoriellen, die Sie fast gefragt:

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

Es funktioniert nicht für fact (0), aber Sie können nicht in den Anwendungsbereich von fact Sorgen machen:)


Masi hat gefragt, ob der funktionale Stil effizienter als Richies Umsetzung ist. Nach meiner schnellen Benchmark (und zu meiner Überraschung!) Ja, ist mein schneller. Aber es gibt ein paar Dinge, die wir tun können, ändern.

Erstens können wir lambda x,y: x*y mit operator.mul ersetzen, wie in einem anderen Kommentar vorgeschlagen. Pythons lambda Betreiber kommen mit einem nicht unerheblichen Aufwand. Zweitens können wir xrange für range ersetzen. xrange sollte im linearen Raum arbeitet, Zahlen wie nötig zurückkehrt, während range die ganze Liste schafft alles auf einmal. (Beachten Sie dann, dass Sie fast sicher xrange für einen zu großen Bereich von Zahlen verwenden müssen)

So ist die neue Definition wird:

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

Zu meiner Überraschung, dies tatsächlich zu einer langsameren Leistung geführt. Hier ist das Q & D-Benchmarks:

>>> 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

Hier ist meine Python-Version, falls jemand will, meine Ergebnisse Cross-Check:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2

wirklich, wäre die einfachste Option sein:

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

ja, irgendwie, es funktioniert.

Wie könnte man nicht daran denken? Ich weiß es nicht.

Eine for Schleife und ein Multiplikator, wirklich Einfachheit ist der beste Weg zu gehen, nicht wahr?

EDIT: Oh, warten Sie, wir für die meisten CPU-efficeint Art und Weise zu arbeiten? ohhhh .....

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top