web-dev-qa-db-fra.com

Python opérations Tuple élément par élément telles que sum

Est-il possible d’obtenir les opérations Tuple dans Python comme ceci:

>>> a = (1,2,3)
>>> b = (3,2,1)
>>> a + b
(4,4,4)

au lieu de:

>>> a = (1,2,3)
>>> b = (3,2,1)
>>> a + b
(1,2,3,3,2,1)

Je sais que cela fonctionne comme ça parce que les méthodes __add__ Et __mul__ Sont définies pour fonctionner comme ça. Donc, le seul moyen serait de les redéfinir?

91
Rodrigo
import operator
Tuple(map(operator.add, a, b))
120
ironfroggy

Utiliser tous les éléments intégrés ..

Tuple(map(sum, Zip(a, b)))
103
Triptych

Cette solution ne nécessite pas d'importation:

Tuple(map(lambda x, y: x + y, Tuple1, Tuple2))
30
Boaz Shvartzman

En quelque sorte, les deux premières réponses ont été combinées, avec un Tweak au code d'Ironfroggy pour qu'il retourne un Tuple:

import operator

class stuple(Tuple):
    def __add__(self, other):
        return self.__class__(map(operator.add, self, other))
        # obviously leaving out checking lengths

>>> a = stuple([1,2,3])
>>> b = stuple([3,2,1])
>>> a + b
(4, 4, 4)

Note: en utilisant self.__class__ au lieu de stuple pour faciliter le sous-classement.

19
Dana
from numpy import *

a = array( [1,2,3] )
b = array( [3,2,1] )

print a + b

donne array([4,4,4]).

Voir http://www.scipy.org/Tentative_NumPy_Tutorial

17
Mike

La compréhension du générateur pourrait être utilisée à la place de la carte. La fonction de carte intégrée n'est pas obsolète, mais elle est moins lisible pour la plupart des gens que la compréhension de liste/générateur/dict. Je vous recommande donc de ne pas utiliser la fonction de carte en général.

Tuple(p+q for p, q in Zip(a, b))
10
Jaehyun Yeom

solution simple sans définition de classe qui retourne Tuple

import operator
Tuple(map(operator.add,a,b))
6
DemonEye

Toute solution de générateur. Pas sûr de la performance (itertools est rapide, cependant)

import itertools
Tuple(x+y for x, y in itertools.izip(a,b))
6
Mike

Oui. Mais vous ne pouvez pas redéfinir les types intégrés. Vous devez les sous-classer:

 class MyTuple (Tuple): 
 def __add __ (auto, autre): 
 si len (auto)! = len (autre): 
 élève ValueError (" Les longueurs de tuple ne correspondent pas ") 
 Renvoie MyTuple (x + y pour (x, y) dans Zip (self, other)) 
3
Doug

encore plus simple et sans utiliser la carte, vous pouvez le faire

>>> Tuple(sum(i) for i in Zip((1, 2, 3), (3, 2, 1)))
(4, 4, 4)
1
LetsPlayYahtzee

Je sous-classe actuellement la classe "Tuple" pour surcharger +, - et *. Je trouve que cela rend le code plus beau et l’écriture plus facile.

class tupleN(Tuple):
    def __add__(self, other):
        if len(self) != len(other):
             return NotImplemented
        else:
             return tupleN(x+y for x,y in Zip(self,other))
    def __sub__(self, other):
        if len(self) != len(other):
             return NotImplemented
        else:
             return tupleN(x-y for x,y in Zip(self,other))
    def __mul__(self, other):
        if len(self) != len(other):
             return NotImplemented
        else:
             return tupleN(x*y for x,y in Zip(self,other))


t1 = tupleN((1,3,3))
t2 = tupleN((1,3,4))
print(t1 + t2, t1 - t2, t1 * t2, t1 + t1 - t1 - t1)
(2, 6, 7) (0, 0, -1) (1, 9, 12) (0, 0, 0)
0
user2012588