2009-01-31 6 views
73

Y at-il de toute façon d'obtenir des opérations de tuple en Python pour travailler comme ceci:opérations tuple Python élément par élément comme somme

>>> 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 la __add__ et __mul__ méthodes sont définies pour fonctionner comme ça. Donc le seul moyen serait de les redéfinir?

Répondre

102
import operator 
tuple(map(operator.add, a, b)) 
+4

Je dirais que c'est le plus solution pythonique. –

+2

Sauf que map() est semi-déprécié. Voir http://www.artima.com/weblogs/viewpost.jsp?thread=98196 pour un article de Guido où il est mentionné comment la carte est mieux écrite comme une liste de compréhension. –

+0

Il souffle aussi si a & b ne contient pas le même nombre d'éléments, ou ne sont pas "addables" (ex: 'map (operator.add, (1,2), (" 3 "," 4 ")) ' –

3

Oui. Mais vous ne pouvez pas redéfinir les types prédéfinis. Vous devez les sous-classe:

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

mais vous ne pouvez pas utiliser la syntaxe tuple. – airportyh

19

Trier COMBINES les deux premières réponses, avec un tweak au code de ironfroggy afin 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: L'utilisation self.__class__ au lieu de stuple pour faciliter sous-classement.

78

En utilisant tous les Encastrements ..

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

Cela semble être la réponse plus simple et supérieure. Pourquoi n'est-ce pas accepté? –

+15

c'est bien, mais techniquement pas ce qui est demandé car map renvoie une liste, pas un tuple ... donc: 'tuple (mappage (somme, zip (a, b))' – Ben

+3

La syntaxe est mystique –

15
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

+5

Cela fonctionnera, mais c'est un peu lourd d'importer numpy juste pour un opération d'addition simple –

5

solution simple sans définition de classe qui retourne tuple

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

Toutes solution génératrice. Vous ne savez pas sur la performance (itertools est rapide, bien que)

import itertools 
tuple(x+y for x, y in itertools.izip(a,b)) 
27

Cette solution ne nécessite pas une importation:

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

Cette solution est également plus rapide que l'autre solution one-liner sans import ('map (sum, zip (a, b))') – Air

7

compréhension du générateur peut être utilisé à 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 liste/générateur/dict, donc je recommande de ne pas utiliser la fonction de carte en général.

tuple(p+q for p, q in zip(a, b)) 
0

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

Dans le cas où quelqu'un besoin d'en moyenne une liste de tuples:

import operator 
from functools import reduce 
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples)) 
Questions connexes