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.