L'itérateur xrange() est très rapide, mais il a un défaut: il ne supporte que les entiers 'int', (et donc ni les 'long' ni les 'float') parce qu'il utilise les types de données du C. En contrepartie, la boucle est très rapide.
Voilà un itérateur qui fait la même chose que xrange, mais qui n'a pas le même défaut.
Un avantage, c'est qu'il permet de conserver les boucles for au lieu de while avec les entiers longs et les flottants, ce qui rend le code plus clair.
Voilà le code proposé:
def xplage(*arg): lga = len(arg) if lga == 1: xmin, xmax, xpas = 0, arg[0], 1 elif lga == 2: xmin, xmax, xpas = arg[0], arg[1], 1 elif lga == 3: xmin, xmax, xpas = arg[0], arg[1], arg[2] else: raise ValueError ("Erreur xplage: nombre d'arguments doit être 1,2,ou 3") if xpas == 0: raise ValueError ("Erreur xplage: le pas ne peut être nul") x = xmin if isinstance(xpas, float): eps = xpas/10.0 else: eps = 0 if xpas>0: if xmax<xmin: raise ValueError ("Erreur xplage: bouclage infini") while x+eps<xmax: yield x x += xpas else: if xmax>xmin: raise ValueError ("Erreur xplage: bouclage infini") while x+eps>xmax: yield x x += xpas
En entrée, on l'utilise de la même façon qu'xrange():
Il faut, bien sûr, que le signe de xpas et celui de xmax-xmin soient les mêmes (sinon, erreur pour bouclage infini)
Il faut aussi xpas!=0 (sinon, erreur: une boucle avec un pas nul n'a guère de sens…)
Exemples d'utilisation:
for x in xplage(7): print x 0 1 2 3 4 5 6
for x in xplage(5,10): print x 5 6 7 8 9
for x in xplage(5,10,2): print x 5 7 9
for x in xplage(5,-5,-2): print x 5 3 1 -1 -3
for x in xplage(9999999999999999999999999999999999999999L, 9999999999999999999999999999999999999999L+10L): print x 9999999999999999999999999999999999999999 10000000000000000000000000000000000000000 10000000000000000000000000000000000000001 10000000000000000000000000000000000000002 10000000000000000000000000000000000000003 10000000000000000000000000000000000000004 10000000000000000000000000000000000000005 10000000000000000000000000000000000000006 10000000000000000000000000000000000000007 10000000000000000000000000000000000000008
Si le pas est un flottant, il faut se prémunir contre des erreurs de comparaison (comme 19.999999999999995<20) avec l'ajout de la variable eps=xpas/10.0.
Par exemple:
for i in xplage(2, 16, 0.01): print i 2 2.01 2.02 2.03 ... 15.97 15.98 15.99
Et ça marche aussi avec les pas négatifs:
for i in xplage(2, -16, -0.01): print i 2 1.99 1.98 1.97 ... -15.97 -15.98 -15.99
Amusez-vous bien!