Le operazioni di tupla in termini di elementi Python come la somma
Domanda
Esiste comunque un modo per far funzionare le operazioni di tupla in Python in questo modo:
>>> a = (1,2,3)
>>> b = (3,2,1)
>>> a + b
(4,4,4)
anziché:
>>> a = (1,2,3)
>>> b = (3,2,1)
>>> a + b
(1,2,3,3,2,1)
So che funziona così perché i metodi __add__
e __mul__
sono definiti per funzionare in questo modo. Quindi l'unico modo sarebbe ridefinirli?
Soluzione
import operator
tuple(map(operator.add, a, b))
Altri suggerimenti
Uso di tutti i built-in ..
tuple(map(sum, zip(a, b)))
Questa soluzione non richiede un'importazione:
tuple(map(lambda x, y: x + y, tuple1, tuple2))
Sorta di combinato le prime due risposte, con una modifica al codice di ironfroggy in modo che restituisca 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: usare self.__class__
invece di stuple
per facilitare la sottoclasse.
from numpy import *
a = array( [1,2,3] )
b = array( [3,2,1] )
print a + b
fornisce array([4,4,4])
.
È possibile utilizzare la comprensione del generatore anziché la mappa. La funzione cartografica integrata non è obsoleta ma è meno leggibile per la maggior parte delle persone rispetto alla comprensione di elenco / generatore / dict, quindi consiglierei di non utilizzare la funzione cartografica in generale.
tuple(p+q for p, q in zip(a, b))
soluzione semplice senza definizione di classe che restituisce tupla
import operator
tuple(map(operator.add,a,b))
Soluzione per tutti i generatori. Non sono sicuro delle prestazioni (itertools è veloce, però)
import itertools
tuple(x+y for x, y in itertools.izip(a,b))
Sì. Ma non puoi ridefinire i tipi predefiniti. Devi sottoclassarli:
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))
ancora più semplice e senza usare la mappa, puoi farlo
>>> tuple(sum(i) for i in zip((1, 2, 3), (3, 2, 1)))
(4, 4, 4)
Al momento ho sottoclasse la " tuple " classe da sovraccaricare +, - e *. Trovo che renda il codice bello e che scriva il codice più facilmente.
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)
Nel caso in cui qualcuno debba fare la media di un elenco di tuple:
import operator
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))