Operaciones de tupla de elementos de Python como suma


99

¿Hay alguna forma de hacer que las operaciones de tupla en Python funcionen así?

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

en vez de:

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

Sé que funciona así porque los métodos __add__y __mul__están definidos para funcionar así. Entonces, ¿la única forma sería redefinirlos?

Respuestas:


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

4
Yo diría que esta es la solución más pitónica.
Matthew Schinckel

3
Excepto que map () está semi-obsoleto. Consulte artima.com/weblogs/viewpost.jsp?thread=98196 para ver un artículo de Guido en el que se menciona cómo se escribe mejor el mapa como una lista de comprensión.
Adam Parkin

También explota si a & b no contienen la misma cantidad de elementos, o no son "sumables" (por ejemplo:map(operator.add, (1,2), ("3", "4"))
Adam Parkin

22
tuple([item1 + item2 for item1, item2 in zip(a, b)])sería el equivalente a una lista de comprensión.
Adam Parkin

11
@AdamParkin, la comprensión del generador es aún mejor tuple(item1 + item2 for item1, item2 in zip(a, b)).
Cristian Ciupitu

118

Utilizando todos los elementos integrados ...

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

2
Esta parece ser la respuesta superior más simple. ¿Por qué no se acepta?
Marc Cenedella

15
es bueno, pero técnicamente no es lo que se pide porque el mapa devuelve una lista, no una tupla ... así que:tuple(map(sum,zip(a,b))
Ben

3
La sintaxis es mística.
anatoly techtonik

2
El beneficio de este es que puede extenderlo a:tuple(map(sum,zip(a,b, c))
Andy Hayden

32

Esta solución no requiere una importación:

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

2
Esta solución también es más rápida que la otra solución de una sola línea sin importación ( map(sum, zip(a, b)))
Air

20

Una especie de combinación de las dos primeras respuestas, con un ajuste en el 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 en self.__class__lugar de stuplepara facilitar la subclasificación.



11

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

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

6

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

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

6

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

3

Si. Pero no puede redefinir los tipos integrados. Tienes que subclasificarlos:

clase MyTuple (tupla):
    def __add __ (yo, otro):
         if len (self)! = len (other):
             elevar ValueError ("las longitudes de tupla no coinciden")
         devuelve MyTuple (x + y para (x, y) en zip (self, other))

pero luego no puede usar la sintaxis de tupla.
airportyh

3

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)

1

Actualmente, hago una subclase de la clase "tupla" para sobrecargar +, - y *. Encuentro 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)

-1

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))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.