Các phép toán tuple khôn ngoan phần tử Python như sum


99

Có cách nào để các hoạt động tuple trong Python hoạt động như thế này không:

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

thay vì:

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

Tôi biết nó hoạt động như vậy vì các __add____mul__phương thức được định nghĩa để hoạt động như vậy. Vì vậy, cách duy nhất sẽ là xác định lại chúng?

Câu trả lời:


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

4
Tôi muốn nói đây là giải pháp khắc nghiệt nhất.
Matthew Schinckel

3
Ngoại trừ map () không được dùng nữa. Xem Artima.com/weblogs/viewpost.jsp?thread=98196 cho một bài báo của Guido, trong đó nó đề cập đến cách bản đồ được viết tốt hơn dưới dạng dễ hiểu danh sách.
Adam Parkin

Nó cũng sẽ nổ nếu a & b không chứa cùng một số phần tử hoặc không phải là "có thể thêm được" (ví dụ:map(operator.add, (1,2), ("3", "4"))
Adam Parkin

22
tuple([item1 + item2 for item1, item2 in zip(a, b)])sẽ tương đương như một danh sách hiểu.
Adam Parkin

11
@AdamParkin, khả năng hiểu của trình tạo thậm chí còn tốt hơn tuple(item1 + item2 for item1, item2 in zip(a, b)).
Cristian Ciupitu

118

Sử dụng tất cả cài sẵn ..

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

2
Đây dường như là câu trả lời đơn giản hơn, ưu việt hơn. Tại sao nó không được chấp nhận?
Marc Cenedella,

15
nó tốt, nhưng về mặt kỹ thuật không phải là những gì được yêu cầu vì bản đồ trả về một danh sách chứ không phải một bộ giá trị ... vì vậy:tuple(map(sum,zip(a,b))
Ben.

3
Cú pháp là thần bí.
anatoly techtonik

2
Lợi ích của việc này là bạn có thể mở rộng nó để:tuple(map(sum,zip(a,b, c))
Andy Hayden

32

Giải pháp này không yêu cầu nhập:

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

2
Giải pháp này cũng nhanh hơn so với giải pháp một lớp lót, không cần nhập khác ( map(sum, zip(a, b)))
Air

20

Sắp xếp kết hợp hai câu trả lời đầu tiên, với một chỉnh sửa đối với mã của ironfroggy để nó trả về một bộ giá trị:

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)

Lưu ý: sử dụng self.__class__thay vì stupleđể dễ phân lớp.



11

Khả năng hiểu của máy phát điện có thể được sử dụng thay cho bản đồ. Chức năng bản đồ tích hợp không lỗi thời nhưng nó kém dễ đọc đối với hầu hết mọi người so với khả năng hiểu danh sách / trình tạo / đọc chính tả, vì vậy tôi khuyên bạn không nên sử dụng chức năng bản đồ nói chung.

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

6

giải pháp đơn giản không có định nghĩa lớp trả về tuple

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

6

Tất cả các giải pháp máy phát điện. Không chắc chắn về hiệu suất (mặc dù itertools nhanh)

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

3

Đúng. Nhưng bạn không thể xác định lại các loại tích hợp. Bạn phải phân loại chúng:

lớp MyTuple (tuple):
    def __add __ (tự, khác):
         if len (self)! = len (other):
             tăng ValueError ("độ dài bộ giá trị không khớp")
         trả về MyTuple (x + y cho (x, y) ở dạng zip (self, other))

nhưng sau đó bạn không thể sử dụng cú pháp tuple.
Airportyh

3

thậm chí đơn giản hơn và không cần sử dụng bản đồ, bạn có thể làm điều đó

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

1

Tôi hiện phân lớp lớp "tuple" thành quá tải +, - và *. Tôi thấy nó làm cho mã đẹp và viết mã dễ dàng hơn.

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

Trong trường hợp ai đó cần tính trung bình một danh sách các bộ giá trị:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.