Operazioni di tupla basate sugli elementi di Python come sum


99

Esiste comunque per far funzionare le operazioni di tuple in Python in questo modo:

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

invece di:

>>> 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 così. Quindi l'unico modo sarebbe ridefinirli?

Risposte:


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

4
Direi che questa è la soluzione più pitonica.
Matthew Schinckel

3
Tranne che map () è semi-deprecato. Vedi artima.com/weblogs/viewpost.jsp?thread=98196 per un articolo di Guido in cui menziona come la mappa sia meglio scritta come comprensione di una lista.
Adam Parkin

Inoltre esplode se a & b non contengono lo stesso numero di elementi o non sono "aggiungibili" (es:map(operator.add, (1,2), ("3", "4"))
Adam Parkin,

22
tuple([item1 + item2 for item1, item2 in zip(a, b)])sarebbe l'equivalente di una lista di comprensione.
Adam Parkin

11
@AdamParkin, le comprensioni del generatore sono ancora migliori tuple(item1 + item2 for item1, item2 in zip(a, b)).
Cristian Ciupitu

118

Utilizzando tutti i built-in ..

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

2
Questa sembra essere la risposta più semplice e migliore. Perché non è accettato?
Marc Cenedella

15
è buono, ma tecnicamente non è quello che viene richiesto perché map restituisce un elenco, non una tupla ... quindi:tuple(map(sum,zip(a,b))
Ben

3
La sintassi è mistica.
anatoly techtonik

2
Il vantaggio di questo è che puoi estenderlo a:tuple(map(sum,zip(a,b, c))
Andy Hayden

32

Questa soluzione non richiede un'importazione:

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

2
Questa soluzione è anche più veloce dell'altra soluzione one-liner senza importazione ( map(sum, zip(a, b)))
Air

20

Una 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 stupleper facilitare la creazione di sottoclassi.



11

La comprensione del generatore potrebbe essere utilizzata al posto della mappa. La funzione mappa incorporata non è obsoleta ma è meno leggibile per la maggior parte delle persone rispetto alla comprensione di elenchi / generatori / dict, quindi consiglierei di non utilizzare la funzione mappa in generale.

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

6

soluzione semplice senza definizione di classe che restituisce tupla

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

6

Tutta la soluzione del generatore. Non sono sicuro delle prestazioni (itertools è veloce, però)

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

3

Sì. Ma non puoi ridefinire i tipi incorporati. Devi sottoclassarli:

class MyTuple (tupla):
    def __add __ (self, other):
         se len (self)! = len (altro):
             raise ValueError ("le lunghezze delle tuple non corrispondono")
         return MyTuple (x + y for (x, y) in zip (self, other))

ma allora non puoi usare la sintassi della tupla.
airportyh

3

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)

1

Attualmente ho sottoclasse la classe "tuple" per sovraccaricare +, - e *. Trovo che renda il codice bello e la scrittura del codice più 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)

-1

Nel caso in cui qualcuno abbia bisogno di 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))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.