Pregunta

¿Existe alguna forma de hacer que las operaciones de tuplas en Python funcionen así?

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

en lugar de:

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

Sé que funciona así porque el __add__ y __mul__ Los métodos están definidos para funcionar así.Entonces, ¿la única manera sería redefinirlos?

¿Fue útil?

Solución

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

Otros consejos

Uso de todos los elementos integrados ..

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

Esta solución no requiere una importación:

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

Más o menos combinó las dos primeras respuestas, con un ajuste al código de ironfroggy para que devuelva una tupla:

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)

Nota: usar self.__class__ en lugar de stuple para facilitar la subclasificación.

from numpy import *

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

print a + b

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

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

Se podría usar la comprensión del generador en lugar del mapa. La función de mapa incorporada no es obsoleta, pero es menos legible para la mayoría de las personas que la comprensión de lista / generador / dictado, por lo que recomendaría no usar la función de mapa en general.

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

solución simple sin definición de clase que devuelve tupla

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

Toda la solución del generador. No estoy seguro del rendimiento (aunque itertools es rápido)

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

Sí Pero no puede redefinir los tipos incorporados. Tienes que subclasificarlos:

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

aún más simple y sin usar el mapa, puedes hacerlo

>>> tuple(sum(i) for i in zip((1, 2, 3), (3, 2, 1)))
(4, 4, 4)

Actualmente subclasifico la " tupla " clase para sobrecargar +, - y *. Creo que hace que el código sea hermoso y que escribir el código sea más fácil.

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)

En caso de que alguien necesite promediar una lista de tuplas:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top