像sum这样的Python元素元组操作


99

无论如何,有没有让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__方法被定义为那样工作。因此,唯一的方法是重新定义它们?

Answers:


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

4
我会说这是最pythonic的解决方案。
马修·辛克尔

3
除了map()是半弃用的。请参阅artima.com/weblogs/viewpost.jsp?thread=98196,了解Guido的文章,其中提到如何更好地将map编写为列表推导
亚当·帕金

如果a和b不包含相同数量的元素或不是“可加的”元素,它也会爆炸(例如:map(operator.add, (1,2), ("3", "4"))
Adam Parkin 2012年

22
tuple([item1 + item2 for item1, item2 in zip(a, b)])等同于列表理解。
亚当·帕金

11
@AdamParkin,发电机理解力甚至更好tuple(item1 + item2 for item1, item2 in zip(a, b))
克里斯蒂安·丘皮图

118

使用所有内置插件

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

2
这似乎是更简单,更好的答案。为什么不接受?
Marc Cenedella

15
这是很好的,但在技术上没有什么要求,因为地图返回一个列表,而不是一个元组...所以:tuple(map(sum,zip(a,b))

3
语法是神秘的。
anatoly techtonik 2014年

2
此操作的好处是您可以将其扩展为:tuple(map(sum,zip(a,b, c))
Andy Hayden


20

对前两个答案进行了某种组合,并对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简化子类化。



11

可以使用生成器理解来代替map。内置的地图功能并不是过时的,但是对于大多数人来说,其可读性不如列表/生成器/字典理解,因此,我建议一般不要使用地图功能。

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

6

没有类定义的简单解决方案,返回元组

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

6

所有发电机解决方案。不确定性能(不过itertools很快)

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

3

是。但是您不能重新定义内置类型。您必须将它们子类化:

类MyTuple(tuple):
    def __add __(自己,其他):
         如果len(self)!= len(other):
             引发ValueError(“元组长度不匹配”)
         返回MyTuple(对于zip中的(x,y)为x(y,y)(self,other))

但是您不能使用元组语法。
airportyh

3

甚至更简单,无需使用地图,您可以做到这一点

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

1

我目前将“元组”类子类化以重载+,-和*。我发现它使代码更漂亮,并使编写代码更容易。

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

如果有人需要平均一个元组列表:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.