2013-07-02 15 views
33

Jaki jest najbardziej elegancki i zwięzły (bez tworzenia własnej klasy z przeciążeniem operatora) wykonywanie arytmetyki krotkowej w Pythonie 2.7?Elegancki sposób wykonywania arytmetycznej krotki

Powiedzmy mam dwie krotki:

a = (10, 10) 
b = (4, 4) 

Moja przeznaczony wynik jest

c = a - b = (6, 6) 

Używam obecnie:

c = (a[0] - b[0], a[1] - b[1]) 

Próbowałem również:

c = tuple([(i - j) for i in a for j in b]) 

, ale wynikiem był (6, 6, 6, 6). Wierzę, że powyższe działa jako zagnieżdżone dla pętli, co powoduje 4 iteracje i 4 wartości w wyniku.

+0

Jeśli wykonujesz wiele z nich i nie musisz ich specjalnie traktować, możesz spojrzeć na numpy –

Odpowiedz

39

Jeśli szukasz szybko, można użyć numpy:

>>> import numpy 
>>> numpy.subtract((10, 10), (4, 4)) 
array([6, 6]) 

i jeśli chcesz zachować go w krotce:

>>> tuple(numpy.subtract((10, 10), (4, 4))) 
(6, 6) 
24

Zastosowanie zip i ekspresja generatora:

c = tuple(x-y for x, y in zip(a, b)) 

Demo:

>>> a = (10, 10) 
>>> b = (4, 4) 
>>> c = tuple(x-y for x, y in zip(a, b)) 
>>> c 
(6, 6) 

Zastosowanie itertools.izip dla pamięci wydajnego rozwiązania.

pomoc na zip:

>>> print zip.__doc__ 
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)] 

Return a list of tuples, where each tuple contains the i-th element 
from each of the argument sequences. The returned list is truncated 
in length to the length of the shortest argument sequence. 
+0

Dzięki za szczegółową odpowiedź! –

+0

Po prostu notatka na 'izip': W Pythonie 3, zwykła funkcja' zip' działa tak jak 'izip' Pythona 2, więc możesz po prostu użyć' zip' jako przykładów w tym show odpowiedzi. –

27

Jednym rozwiązaniem byłoby,

>>> from operator import sub 
>>> c = tuple(map(sub, a, b)) 
>>> c 
(6, 6) 

I itertools.imap może służyć jako zamiennik map.

Oczywiście można również korzystać z innych funkcji z operator do add, mul, div itp

Ale chciałbym poważnie rozważyć przeniesienie do innej struktury danych, ponieważ nie sądzę, tego typu problemu jest zdolny do tuple s

+0

Dzięki. +1 dla operatora i mapy. –

2

Można to również zrobić tak ładnie bez importu w ogóle, chociaż lambda jest często niepożądane:

tuple(map(lambda x, y: x - y, a, b)) 

Jeśli szukasz, aby odległość między dwoma punktami na powiedzmy współrzędnych 2d samolot powinieneś użyć wartości bezwzględnej odejmowania par.

tuple(map(lambda x ,y: abs(x - y), a, b)) 
0

my element mądry krotka arytmetyczna pomocniczych

obsługiwanych operacji: +, -,/* d

operacja do 'D' oblicza odległość między dwoma punktami na 2D współrzędnych płaszczyzny

def tuplengine(tuple1, tuple2, operation): 
    """ 
    quick and dirty, element-wise, tuple arithmetic helper, 
    created on Sun May 28 07:06:16 2017 
    ... 
    tuple1, tuple2: [named]tuples, both same length 
    operation: '+', '-', '/', '*', 'd' 
    operation 'd' returns distance between two points on a 2D coordinate plane (absolute value of the subtraction of pairs) 
    """ 
    assert len(tuple1) == len(tuple2), "tuple sizes doesn't match, tuple1: {}, tuple2: {}".format(len(tuple1), len(tuple2)) 
    assert isinstance(tuple1, tuple) or tuple in type(tuple1).__bases__, "tuple1: not a [named]tuple" 
    assert isinstance(tuple2, tuple) or tuple in type(tuple2).__bases__, "tuple2: not a [named]tuple" 
    assert operation in list("+-/*d"), "operation has to be one of ['+','-','/','*','d']" 
    return eval("tuple(a{}b for a, b in zip(tuple1, tuple2))".format(operation)) \ 
    if not operation == "d" \ 
     else eval("tuple(abs(a-b) for a, b in zip(tuple1, tuple2))") 
Powiązane problemy