OVH Cloud OVH Cloud

sort, __cmp__ et OverflowError

2 réponses
Avatar
Blaise Li
Bonjour,

j'ai défini une classe d'objets dont la méthode __cmp__ est redéfinie. En
gros (je simplifie en espérant ne pas oublier ce qui est important), ça
donne ça:

-----
class Newclass(object):
def __init__(self, value):
self.value = value

def __cmp__(self, other):
return self.value - other.value

a = Newclass(10000000000)
b = Newclass(2)
c = Newclass(3)
list = [a, c, b]
list.sort()
-----

Et je me prends l'erreur suivante:

OverflowError: long int too large to convert to int
Après quelques essais pour produire l'erreur, il me semble que sort
plante si __cmp__ renvoie une différence trop grande.

Le fait que l'attribut value puisse être si grand chez certains de mes
objets est du au fait que cet attribut est une somme de puissances de 2
me servant à représenter des ensembles d'un certain nombre d'éléments,
chacun étant représenté par une puissance de 2.

Voyez vous un moyen de contourner ce problème ?
Peut-être suffit-il de remplacer la sortie de la méthode __cmp__ par un
petit entier de même signe que self.value - other.value ...

Devrais-je utiliser des objets de type "set" plutot que des sommes de
puissances de 2 ? Je m'étais habitué à faire mes comparaisons d'ensembles
en faisant des opérations sur les valeurs les représentant avant de
savoir qu'il existait le type "set". Je n'avais pas eu de problèmes
jusqu'à ce que je découvre la méthode __cmp__ et que j'essaie de jouer
avec.

bli, qui réfléchit au fur et à mesure qu'il expose son problème.

2 réponses

Avatar
Amaury Forgeot d'Arc
Bonjour,

j'ai défini une classe d'objets dont la méthode __cmp__ est redéfinie. En
gros (je simplifie en espérant ne pas oublier ce qui est important), ça
donne ça:

-----
class Newclass(object):
def __init__(self, value):
self.value = value

def __cmp__(self, other):
return self.value - other.value

a = Newclass(10000000000)
b = Newclass(2)
c = Newclass(3)
list = [a, c, b]
list.sort()
-----

Et je me prends l'erreur suivante:

OverflowError: long int too large to convert to int
Après quelques essais pour produire l'erreur, il me semble que sort
plante si __cmp__ renvoie une différence trop grande.

Le fait que l'attribut value puisse être si grand chez certains de mes
objets est du au fait que cet attribut est une somme de puissances de 2
me servant à représenter des ensembles d'un certain nombre d'éléments,
chacun étant représenté par une puissance de 2.

Voyez vous un moyen de contourner ce problème ?
Peut-être suffit-il de remplacer la sortie de la méthode __cmp__ par un
petit entier de même signe que self.value - other.value ...


Connais-tu la fonction cmp(x ,y) ? Avec des nombres entiers, elle
renvoie toujours -1, 0, ou 1.
Je suis d'avis de faire fonctionner ta fonction __cmp__ de la même
manière (après tout, cmp est censé appeller __cmp__, tout comme len(x)
appelle x.__len__()...) On peut même l'écrire élégamment :

def __cmp__(self, other):
return cmp(self.value, other.value)


Devrais-je utiliser des objets de type "set" plutot que des sommes de
puissances de 2 ? Je m'étais habitué à faire mes comparaisons d'ensembles
en faisant des opérations sur les valeurs les représentant avant de
savoir qu'il existait le type "set". Je n'avais pas eu de problèmes
jusqu'à ce que je découvre la méthode __cmp__ et que j'essaie de jouer
avec.

bli, qui réfléchit au fur et à mesure qu'il expose son problème.


Avatar
Blaise Li
Amaury Forgeot d'Arc wrote in message
<emcbdj$2cpq$:

Connais-tu la fonction cmp(x ,y) ? Avec des nombres entiers, elle
renvoie toujours -1, 0, ou 1.
Je suis d'avis de faire fonctionner ta fonction __cmp__ de la même
manière (après tout, cmp est censé appeller __cmp__, tout comme len(x)
appelle x.__len__()...) On peut même l'écrire élégamment :

def __cmp__(self, other):
return cmp(self.value, other.value)


Effectivement, c'est plus propre. Au début, j'avais espéré pouvoir
récupérer un résultat plus nuancé que juste -1, 0, ou 1 à la sortie de
__cmp__, mais si ça pose problème à sort(), je vais me rabattre sur
cmp().

bli