Toplam gibi Python öğe bazlı tuple işlemleri


101

Python'da tuple işlemlerinin şu şekilde çalışması için zaten var mı:

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

onun yerine:

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

Böyle çalıştığını biliyorum çünkü __add__ve __mul__yöntemleri böyle çalışmak için tanımlandı. Yani tek yol onları yeniden tanımlamak mı?

Yanıtlar:


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

4
Bunun en pitonik çözüm olduğunu söyleyebilirim.
Matthew Schinckel

3
Haritanın () yarı kullanımdan kaldırılması dışında. Guido tarafından yazılan ve haritanın bir liste anlayışı olarak nasıl daha iyi yazıldığından bahseden bir makale için artima.com/weblogs/viewpost.jsp?thread=98196 adresine bakın .
Adam Parkin

Ayrıca a & b aynı sayıda öğe içermiyorsa veya "eklenebilir" değilse de patlar (örn:map(operator.add, (1,2), ("3", "4"))
Adam Parkin

23
tuple([item1 + item2 for item1, item2 in zip(a, b)])liste anlama ile eşdeğer olacaktır.
Adam Parkin

12
@AdamParkin, jeneratör anlayışları daha da iyi tuple(item1 + item2 for item1, item2 in zip(a, b)).
Cristian Ciupitu

118

Tüm yerleşikler kullanılıyor ..

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

2
Bu daha basit, daha üstün cevap gibi görünüyor. Neden kabul edilmiyor?
Marc Cenedella

15
bu iyi, ama teknik olarak istenen şey değil çünkü harita bir liste döndürüyor, bir demet değil ... yani:tuple(map(sum,zip(a,b))
Ben

3
Sözdizimi mistiktir.
anatoly techtonik

2
Bunun yararı, aşağıdakilere kadar uzatabilmenizdir:tuple(map(sum,zip(a,b, c))
Andy Hayden

32

Bu çözüm, içe aktarma gerektirmez:

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

2
Bu çözüm aynı zamanda diğer içe aktarmasız, tek astarlı çözümden daha hızlıdır ( map(sum, zip(a, b)))
Air

20

İlk iki yanıtı, ironfroggy'nin kodunda bir tuple verecek şekilde değiştirerek birleştirin:

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)

Not: alt sınıflamayı kolaylaştırmak için self.__class__yerine kullanın stuple.



11

Harita yerine üretici anlayışı kullanılabilir. Yerleşik harita işlevi eski değildir, ancak çoğu insan için liste / oluşturucu / dikte anlamadan daha az okunabilir, bu nedenle genel olarak harita işlevini kullanmamanızı öneririm.

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

6

tuple döndüren sınıf tanımı olmayan basit çözüm

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

6

Tüm jeneratör çözümü. Performanstan emin değilim (yinelemeler hızlı olsa da)

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

3

Evet. Ancak yerleşik türleri yeniden tanımlayamazsınız. Onları alt sınıflara ayırmalısınız:

sınıf MyTuple (tuple):
    def __add __ (kendi, diğer):
         eğer len (öz)! = len (diğer):
             ValueError'ı yükselt ("demet uzunlukları eşleşmiyor")
         MyTuple'ı döndür (x + y for (x, y) in zip (self, other))

ancak o zaman demet sözdizimini kullanamazsınız.
airportyh

3

daha da basit ve harita kullanmadan bunu yapabilirsiniz

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

1

Şu anda "tuple" sınıfını +, - ve * 'yi aşırı yüklemek için alt sınıflara ayırıyorum. Bunun kodu güzelleştirdiğini ve kodu yazmayı kolaylaştırdığını görüyorum.

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

Birinin bir grup listesinin ortalamasını alması gerektiğinde:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.