2009-08-02 7 views
23

Existe-t-il un moyen simple et rapide d'utiliser sum() avec des valeurs non entières?Les valeurs sum() et non-entiers de python

Je peux l'utiliser comme ceci:

class Foo(object): 
    def __init__(self,bar) 
     self.bar=bar 

mylist=[Foo(3),Foo(34),Foo(63),200] 
result=sum(mylist) # result should be 300 

J'ai essayé et remplaçant __add____int__ etc, mais je ne l'ai pas trouvé une solution encore

EDIT:

Le la solution est de mettre en œuvre:

def __radd__(self, other): 
    return other + self.bar 

comme Will a suggéré dans son post. Mais comme toujours, tous les chemins mènent à Rome, mais je pense que cela est la meilleure solution car je ne ai pas besoin __add__ dans ma classe

Répondre

25

Son un peu délicat - la fonction somme() prend le départ et l'ajoute à l'autre et ainsi de suite

Vous devez implémenter la méthode __radd__:

class T: 
    def __init__(self,x): 
     self.x = x 
    def __radd__(self, other): 
     return other + self.x 

test = (T(1),T(2),T(3),200) 
print sum(test) 
+0

Je pense que l'implémentation de __radd__ est la meilleure solution, car elle n'a pas besoin de map(), de reduce() ou d'importation de modules supplémentaires. – sloth

5

Essayez:

import operator 
result=reduce(operator.add, mylist) 

somme() fonctionne probablement plus rapide, mais il est spécialisé pour les numéros intégrés uniquement. Bien sûr, vous devez toujours fournir une méthode pour ajouter vos objets Foo(). par exemple si plein:

class Foo(object): 
    def __init__(self, i): self.i = i 
    def __add__(self, other): 
     if isinstance(other, int): 
      return Foo(self.i + other) 
     return Foo(self.i + other.i) 
    def __radd__(self, other): 
     return self.__add__(other) 

import operator 
mylist = [Foo(42), Foo(36), Foo(12), 177, Foo(11)] 
print reduce(operator.add, mylist).i 
+0

de functools importer réduire # PY3 –

+0

C'est la solution la plus générique, qui fonctionne pour tous les types implémentant '__add__', y compris ceux qui ne sont pas conçus pour fonctionner avec' sum (...) ', comme les quantités avec des unités dans la bibliothèque' pint'. – gerrit

3

Essayez d'utiliser la méthode __int__ puis cartographier chaque élément dans la liste à la fonction int pour obtenir les valeurs sur:

class Foo(object): 
    def __init__(self,bar): 
     self.bar = bar 
    def __int__(self): 
     return self.bar 

mylist = [Foo(3),Foo(34),Foo(63),200] 
result = sum(map(int,mylist)) 
print(result) 
5

Ou si vous ne voulez pas importer quoi que ce soit,

result=reduce((lambda x,y:x+y), mylist 

un autre petit avantage est que vous ne devez pas déclarer nécessairement un ajouter méthode dans le cadre de vos objets Foo, si cela se trouve être la seule circonstance dans laquelle vous voulez faire l'addition. (Mais il ne serait probablement pas de mal à définir ajouter flexibilité pour l'avenir.)

16

Vous devrez peut-être mettre en œuvre la fonction __radd__, ce qui représente « reverse ajouter » et est appelée lorsque les arguments ne peuvent pas être résolus la direction "en avant". Par exemple, x + y est évalué comme x.__add__(y) si possible, mais si cela n'existe pas, alors Python essaie y.__radd__(x).

Puisque la fonction sum() commence par l'entier 0, la première chose qu'il fait est d'essayer d'évaluer:

0 + Foo(3) 

qui exigera que vous implémentez Foo.__radd__.

Questions connexes