web-dev-qa-db-ja.com

タプル演算を実行するエレガントな方法

Python 2.7?

2つのタプルがあるとします。

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

私の意図した結果は

c = a - b = (6, 6)

私は現在使用しています:

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

私も試しました:

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

しかし、結果は(6, 6, 6, 6)。上記はネストされたforループとして機能し、結果として4つの反復と4つの値が得られると思います。

47
user1737647

高速を探している場合は、numpyを使用できます。

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

そして、タプルに保持したい場合:

>>> Tuple(numpy.subtract((10, 10), (4, 4)))
(6, 6)
60
vroomfondel

1つのオプションは、

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

そして itertools.imap は、mapの代わりとして使用できます。

もちろん、 operator からaddmuldivなどの他の関数も使用できます。

しかし、このタイプの問題はTuplesに適合しないと思うので、別のデータ構造に移行することを真剣に検討します。

32
Jared

Zipとジェネレーター式を使用します。

c = Tuple(x-y for x, y in Zip(a, b))

デモ:

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

つかいます - itertools.izip メモリ効率のよいソリューション。

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.
27

ラムダは多くの場合望ましくありませんが、これはまったくインポートせずに同じようにうまく行うこともできます:

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

たとえば、2D座標平面上の2点間の距離を取得する場合は、ペアの減算の絶対値を使用する必要があります。

Tuple(map(lambda x ,y: abs(x - y), a, b))
3
miigotu

JFYI、私のラップトップでの100,000回の反復での実行時間

np.subtract(a, b):0.18578505516052246

Tuple(x - y for x, y in Zip(a, b)):0.09348797798156738

Tuple(map(lambda x, y: x - y, a, b)):0.07900381088256836

from operator import sub Tuple(map(sub, a, b)):0.044342041015625

オペレータは私にとってよりエレガントに見えます。

2
Kohei Kawasaki

川崎Ko平の答えに加えて、速度のために、元のソリューションは実際には最速でした。

>>> timeit.timeit('Tuple(map(add, a, b))',number=1000000,setup='from operator import add; a=(10,11); b=(1,2)')
0.6502681339999867
>>> timeit.timeit('(a[0] - b[0], a[1] - b[1])',number=1000000,setup='from operator import add; a=(10,11); b=(1,2)')
0.19015854899998885
>>> 
0
Skidushe

私の要素ごとのタプル算術ヘルパー

サポートされている操作:+、-、/、*、d

operation = 'd'は、2D座標平面上の2点間の距離を計算します

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 ))")
0
internety