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.