Question

Y a-t-il un moyen d'obtenir que les opérations de tuple en Python fonctionnent comme suit:

>>> 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?

Était-ce utile?

La solution

import operator
tuple(map(operator.add, a, b))

Autres conseils

Utilisation de tous les éléments intégrés ..

tuple(map(sum, zip(a, b)))

Cette solution ne nécessite pas d'importation:

tuple(map(lambda x, y: x + y, tuple1, tuple2))

En quelque sorte, les deux premières réponses ont été combinées, avec un ajustement du code d'Ironfroggy afin qu'il renvoie 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)

Remarque: utilisez self.__class__ au lieu de stuple pour faciliter les sous-classes.

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

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

solution simple sans définition de classe renvoyant le tuple

import operator
tuple(map(operator.add,a,b))

Toute la solution du 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))

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

class MyTuple(tuple):
    def __add__(self, other):
         if len(self) != len(other):
             raise ValueError("tuple lengths don't match")
         return MyTuple(x + y for (x, y) in zip(self, other))

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)

Je sous-classe actuellement le " tuple & "; classe à 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)

Au cas où quelqu'un aurait besoin de faire la moyenne d'une liste de n-uplets:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top