Question

Mon 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

je reçois l'erreur

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

Comment créer une fonction factorielle en Python?

Était-ce utile?

La solution

Voici votre code, corrigé et fonctionnel:

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

print fact

(Le zéro factoriel est un, pour tous ceux qui ne le savaient pas - je devais le rechercher. 8 -)

Vous avez besoin de deux points après si , sinon , pour , etc., et la façon dont pour fonctionne Python est différent de C.

Autres conseils

La ligne sur laquelle votre erreur est activée doit être lue

if number == 0:

Notez les deux points à la fin.

De plus, vous devrez ajouter les mêmes deux-points après les options else et for. Les deux points fonctionnent de la même manière que {} dans d'autres langues.

Enfin, ce n’est pas comme cela que les boucles for fonctionnent en Python. Le code que vous souhaitez utiliser cette liste serait

for x in range(1,number):

Ce qui aurait le même effet que ce que vous avez écrit si vous le mettiez dans un langage de style C.

EDIT: Oops, la boucle for que j’ai donnée était erronée, elle aurait inclus 0. J'ai mis à jour le code pour corriger cela.

Je comprends que vous essayez probablement de le mettre en œuvre vous-même pour des raisons pédagogiques.

Toutefois, dans le cas contraire, je vous recommande d'utiliser la fonction factorielle intégrée aux modules math (remarque: requiert Python 2.6 ou supérieur):

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

Ce module est écrit en C, et en tant que tel, il sera beaucoup plus rapide que de l’écrire en python. (Bien que, si vous ne calculez pas de grandes factorielles, ce ne sera pas vraiment trop lent de toute façon).

La raison pour laquelle la fonction fact (n) de Mark Rushakoff était tellement plus efficace était qu’il manquait la fonction reduction (). Ainsi, le calcul n’a jamais réellement eu lieu.

Corrigé il lit (et je reçois):

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

Résultat obtenu pour 1500 !, 1000x:

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

Et oui, j'ai vérifié qu'ils donnent tous la même valeur! Je ne comprends pas pourquoi le lambda xrange est tellement pire que la gamme lambda. Hmmm. Version: PythonWin 2.6.2 (r262: 71605, 14 avr. 2009, 22:40:02) [MSC v.1500 32 bits (Intel)] sur win32.

Hmm ... en le relançant, j'obtiens quelque chose de plus crédible

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

Et sur Python 2.6.5 (r265: 79063, 12 juin 2010, 17:07:01) [GCC 4.3.4 20090804 (version) 1] sur cygwin:

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

Tout dans le bruit vraiment, n'est-ce pas?

Voici un factoriel fonctionnel que vous avez presque demandé:

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

Cela ne fonctionne pas pour les faits (0), mais vous pouvez vous en préoccuper en dehors du champ de fait :)

Masi a demandé si le style fonctionnel était plus efficace que l'implémentation de Richie. Selon mes repères rapides (et à ma grande surprise!), Oui, le mien est plus rapide. Mais nous pouvons faire quelque chose pour changer.

Premièrement, nous pouvons remplacer lambda x, y: x * y par operator.mul comme suggéré dans un autre commentaire. L'opérateur lambda de Python s'accompagne d'une surcharge non négligeable. Deuxièmement, nous pouvons substituer xrange à plage . xrange doit fonctionner dans un espace linéaire, en renvoyant des nombres si nécessaire, tandis que plage crée la liste complète en une fois. (Notez donc que vous devez certainement utiliser xrange pour une plage de nombres excessivement grande)

La nouvelle définition devient:

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

À ma grande surprise, les performances ont été ralenties. Voici les points de repère 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

Voici ma version Python au cas où quelqu'un voudrait vérifier ses résultats:

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

vraiment, l'option la plus simple serait:

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

oui, en quelque sorte, cela fonctionne.

Comment pouvez-vous ne pas penser à cela? Je ne sais pas.

Une boucle pour et un multiplicateur, c'est vraiment la simplicité qui convient, pas vrai?

EDIT: Oh, attendez, nous travaillons pour le moyen le plus efficace? ohhhh .....

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top