Outils pour utilisateurs

Outils du site


xplage

Un xrange qui accepte les entiers longs et les flottants

Objectif

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.

Code

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

  • avec un seul argument: c'est xmax (xmin=0, xpas=1)
  • avec 2 arguments: ce sont xmin et xmax (xpas=1)
  • avec 3 arguments: ce sont xmin, xmax et xpas

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!

xplage.txt · Dernière modification: 2011/03/13 07:38 par tyrtamos

Outils de la page