Operasi tupel bijak dengan elemen Python seperti sum


99

Apakah ada cara untuk membuat operasi tupel dengan Python bekerja seperti ini:

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

dari pada:

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

Saya tahu ini berfungsi seperti itu karena __add__dan __mul__metode didefinisikan untuk bekerja seperti itu. Jadi satu-satunya cara adalah dengan mendefinisikannya kembali?

Jawaban:


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

4
Saya akan mengatakan ini adalah solusi paling pythonic.
Matthew Schinckel

3
Kecuali map () itu semi-deprecated. Lihat artima.com/weblogs/viewpost.jsp?thread=98196 untuk artikel oleh Guido yang menyebutkan bagaimana peta lebih baik ditulis sebagai pemahaman daftar.
Adam Parkin

Ini juga meledak jika a & b tidak berisi jumlah elemen yang sama, atau tidak "dapat ditambahkan" (mis:map(operator.add, (1,2), ("3", "4"))
Adam Parkin

22
tuple([item1 + item2 for item1, item2 in zip(a, b)])akan menjadi setara dengan pemahaman daftar.
Adam Parkin

11
@AdamParkin, pemahaman generator bahkan lebih baik tuple(item1 + item2 for item1, item2 in zip(a, b)).
Cristian Ciupitu

118

Menggunakan semua bawaan ..

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

2
Tampaknya ini adalah jawaban yang lebih sederhana dan lebih unggul. Mengapa tidak diterima?
Marc Cenedella

15
itu bagus, tapi secara teknis bukan apa yang diminta karena peta mengembalikan daftar, bukan tuple ... jadi:tuple(map(sum,zip(a,b))
Ben

3
Sintaksnya adalah mistik.
anatoly techtonik

2
Manfaat yang satu ini adalah Anda dapat memperluasnya ke:tuple(map(sum,zip(a,b, c))
Andy Hayden

32

Solusi ini tidak memerlukan impor:

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

2
Solusi ini juga lebih cepat daripada solusi satu baris tanpa impor lainnya ( map(sum, zip(a, b)))
Air

20

Urutkan gabungan dua jawaban pertama, dengan tweak ke kode ironfroggy sehingga mengembalikan tupel:

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)

Catatan: menggunakan self.__class__bukannya stuplememudahkan subclassing.



11

Pemahaman generator dapat digunakan sebagai pengganti peta. Fungsi peta bawaan tidak usang tetapi kurang dapat dibaca oleh kebanyakan orang daripada pemahaman daftar / generator / dikt, jadi saya merekomendasikan untuk tidak menggunakan fungsi peta secara umum.

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

6

solusi sederhana tanpa definisi kelas yang mengembalikan tupel

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

6

Semua solusi generator. Tidak yakin dengan kinerja (itertools cepat, meskipun)

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

3

Iya. Tapi Anda tidak bisa mendefinisikan ulang tipe bawaan. Anda harus membuat subkelasnya:

kelas MyTuple (tuple):
    def __add __ (diri sendiri, lainnya):
         jika len (self)! = len (other):
             meningkatkan ValueError ("panjang tuple tidak cocok")
         return MyTuple (x + y untuk (x, y) di zip (self, other))

tetapi kemudian Anda tidak dapat menggunakan sintaks tupel.
airportyh

3

lebih sederhana dan tanpa menggunakan peta, Anda dapat melakukannya

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

1

Saat ini saya membuat subkelas kelas "tuple" untuk membebani +, - dan *. Saya merasa itu membuat kode menjadi indah dan menulis kode lebih mudah.

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

Jika seseorang perlu membuat daftar rata-rata tupel:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.