Forma elegante de realizar aritmética de tuplas


¿Cuál es la forma más elegante y concisa (sin crear mi propia clase con sobrecarga de operadores) de realizar aritmética de tuplas en Python 2.7?

Digamos que tengo dos tuplas:

a = (10, 10)
b = (4, 4)

Mi resultado deseado es

c = a - b = (6, 6)

Actualmente uso:

c = (a[0] - b[0], a[1] - b[1])

También intenté:

c = tuple([(i - j) for i in a for j in b])

Pero el resultado fue (6, 6, 6, 6). Creo que lo anterior funciona como un anidado para bucles que resulta en 4 iteraciones y 4 valores en el resultado.

Author: Jason Sundram, 2013-07-02

5 answers

Si estás buscando rápido, puedes usar numpy:

>>> import numpy
>>> numpy.subtract((10, 10), (4, 4))
array([6, 6])

Y si quieres mantenerlo en una tupla:

>>> tuple(numpy.subtract((10, 10), (4, 4)))
(6, 6)
 47
Author: vroomfondel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-02 05:52:43

Una opción sería,

>>> from operator import sub
>>> c = tuple(map(sub, a, b))
>>> c
(6, 6)

Y itertools.imap puede servir como reemplazo de map.

Por supuesto, también puede utilizar otras funciones de operator a add, mul, div, etc.

Pero consideraría seriamente pasar a otra estructura de datos ya que no creo que este tipo de problema sea adecuado para tuple s

 29
Author: Jared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-02 05:44:18

Use zip y una expresión generadora:

c = tuple(x-y for x, y in zip(a, b))

Demo:

>>> a = (10, 10)
>>> b = (4, 4)
>>> c = tuple(x-y for x, y in zip(a, b))
>>> c
(6, 6)

Uso itertools.izip para una solución eficiente de memoria.

Ayuda en zip:

>>> print zip.__doc__
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

Return a list of tuples, where each tuple contains the i-th element
from each of the argument sequences.  The returned list is truncated
in length to the length of the shortest argument sequence.
 26
Author: Ashwini Chaudhary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-26 22:17:49

Esto también se puede hacer de la misma manera sin importar nada, aunque lambda es a menudo indeseable:

tuple(map(lambda x, y: x - y, a, b))

Si está buscando obtener la distancia entre dos puntos en un plano de coordenadas 2d, debe usar el valor absoluto de la resta de los pares.

tuple(map(lambda x ,y: abs(x - y), a, b))
 2
Author: miigotu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-04 08:47:36

Mi ayudante aritmético de tupla en cuanto a elementos

Operaciones soportadas:+, -,/,*, d

Operation = ' d ' calcula la distancia entre dos puntos en un plano de coordenadas 2D

def tuplengine(tuple1, tuple2, operation):
    """ 
    quick and dirty, element-wise, tuple arithmetic helper,
    created on Sun May 28 07:06:16 2017
    ...
    tuple1, tuple2: [named]tuples, both same length
    operation: '+', '-', '/', '*', 'd'
    operation 'd' returns distance between two points on a 2D coordinate plane (absolute value of the subtraction of pairs)
    """
    assert len(tuple1) == len(tuple2), "tuple sizes doesn't match, tuple1: {}, tuple2: {}".format(len(tuple1), len(tuple2))
    assert isinstance(tuple1, tuple) or tuple in type(tuple1).__bases__, "tuple1: not a [named]tuple"
    assert isinstance(tuple2, tuple) or tuple in type(tuple2).__bases__, "tuple2: not a [named]tuple"
    assert operation in list("+-/*d"), "operation has to be one of ['+','-','/','*','d']"
    return eval("tuple( a{}b for a, b in zip( tuple1, tuple2 ))".format(operation)) \
    if not operation == "d" \
      else eval("tuple( abs(a-b) for a, b in zip( tuple1, tuple2 ))")
 0
Author: internety,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-28 07:48:58