Операции с кортежами на основе элементов Python, такие как sum

StackOverflow https://stackoverflow.com/questions/497885

  •  20-08-2019
  •  | 
  •  

Вопрос

Есть ли способ заставить операции с кортежами в Python работать следующим образом:

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

вместо того , чтобы:

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

Я знаю, что это работает именно так, потому что __add__ и __mul__ методы определены для такой работы.Значит, единственным способом было бы переопределить их?

Это было полезно?

Решение

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

Другие советы

Используя все встроенные модули..

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

Это решение не требует импорта:

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

Своего рода объединил первые два ответа, изменив код ironfroggy так, чтобы он возвращал кортеж:

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)

Примечание:используя self.__class__ вместо того , чтобы stuple чтобы облегчить разделение на подклассы.

from numpy import *

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

print a + b

дает array([4,4,4]).

Видишь http://www.scipy.org/Tentative_NumPy_Tutorial

Понимание генератора можно было бы использовать вместо карты.Встроенная функция map не устарела, но она менее удобочитаема для большинства людей, чем понимание списка / генератора / диктатора, поэтому я бы рекомендовал не использовать функцию map вообще.

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

простое решение без определения класса, которое возвращает кортеж

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

Полностью генераторное решение.Не уверен в производительности (хотя itertools работает быстро)

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

ДА.Но вы не можете переопределить встроенные типы.Вы должны разделить их на подклассы:

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

еще проще и без использования map вы можете сделать это

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

В настоящее время я создаю подкласс класса "tuple" для перегрузки +,- и *.Я нахожу, что это делает код красивым и упрощает написание кода.

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)

На случай, если кому-то понадобится усреднить список кортежей:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top