Операції кортежу з елементами Python, як сума


99

Чи все-таки потрібно змусити операції кортежу в Python працювати так:

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

замість:

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

Я знаю, що це працює так, тому що методи __add__та __mul__методи визначені для роботи так. Тож єдиним способом було б їх переосмислити?

Відповіді:


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

4
Я б сказав, що це найбільш пітонічне рішення.
Меттью Шинкель

3
За винятком того, що map () є напівзастареним. Дивіться у статті artima.com/weblogs/viewpost.jsp?thread=98196 статтю від Guido, де йдеться про те, як краще писати карту як розуміння списку.
Адам Паркін

Він також вибухає, якщо в & b не міститься однакова кількість елементів, або вони не "доступні" (наприклад:map(operator.add, (1,2), ("3", "4"))
Адам Паркін

22
tuple([item1 + item2 for item1, item2 in zip(a, b)])було б еквівалентом як розуміння списку.
Адам Паркін

11
@AdamParkin, розуміння генератора ще краще tuple(item1 + item2 for item1, item2 in zip(a, b)).
Крістіан Цюпіту

118

Використання всіх вбудованих ..

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

2
Здається, це є простішою, вищою відповіддю. Чому його не прийнято?
Марк Сенеделла

15
це добре, але технічно не те, що просять, тому що карта повертає список, а не кортеж ... так:tuple(map(sum,zip(a,b))
Ben

3
Синтаксис містичний.
anatoly techtonik

2
Перевага цього полягає в тому, що ви можете поширити його на:tuple(map(sum,zip(a,b, c))
Енді Хейден,

32

Це рішення не потребує імпорту:

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

2
Це рішення також швидше, ніж інше неімпортне однолінійне рішення ( map(sum, zip(a, b)))
Повітря

20

Сортуйте комбіновані перші два відповіді, підлаштовуючи код ironfroggy, щоб він повертав кортеж:

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)

Примітка: використання self.__class__замість того, stupleщоб полегшити підкласифікацію.



11

Розуміння генератора може використовуватися замість карти. Вбудована функція карти не застаріла, але для більшості людей вона менш читабельна, ніж розуміння списку / генератора / дикту, тому я рекомендую взагалі не використовувати функцію карти.

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

6

просте рішення без визначення класу, яке повертає кортеж

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

6

Все рішення генератора. Не впевнений у продуктивності (хоча itertools швидкий)

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

3

Так. Але ви не можете переосмислити вбудовані типи. Ви повинні підкласифікувати їх:

клас MyTuple (кортеж):
    def __add __ (самостійна, інша):
         якщо len (само)! = len (інше):
             підвищити ValueError ("довжина кортежу не збігається")
         повернути MyTuple (x + y для (x, y) в zip (самостійна, інша))

але тоді ви не можете використовувати синтаксис кортежу.
аеропорт

3

навіть простіше і без використання карти ви можете це зробити

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

1

В даний час я підклас класу "кортеж" для перевантаження +, - і *. Я вважаю, що це робить код красивим і писати код простіше.

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

У випадку, якщо комусь потрібно середній перелік кортежів:

import operator 
from functools import reduce
tuple(reduce(lambda x, y: tuple(map(operator.add, x, y)),list_of_tuples))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.