Python 执行元组算术的优雅方式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17418108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Elegant way to perform tuple arithmetic
提问by
What is the most elegant and concise way (without creating my own class with operator overloading) to perform tuple arithmetic in Python 2.7?
在 Python 2.7 中执行元组算术的最优雅和简洁的方法是什么(无需创建我自己的带有运算符重载的类)?
Lets say I have two tuples:
假设我有两个元组:
a = (10, 10)
b = (4, 4)
My intended result is
我的预期结果是
c = a - b = (6, 6)
I currently use:
我目前使用:
c = (a[0] - b[0], a[1] - b[1])
I also tried:
我也试过:
c = tuple([(i - j) for i in a for j in b])
but the result was (6, 6, 6, 6)
. I believe the above works as a nested for loops resulting in 4 iterations and 4 values in the result.
但结果是(6, 6, 6, 6)
。我相信上述内容作为嵌套的 for 循环工作,导致结果中有 4 次迭代和 4 个值。
采纳答案by vroomfondel
If you're looking for fast, you can use numpy:
如果你正在寻找快速,你可以使用 numpy:
>>> import numpy
>>> numpy.subtract((10, 10), (4, 4))
array([6, 6])
and if you want to keep it in a tuple:
如果你想把它保存在一个元组中:
>>> tuple(numpy.subtract((10, 10), (4, 4)))
(6, 6)
回答by Ashwini Chaudhary
Use zip
and a generator expression:
使用zip
和生成器表达式:
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)
Use itertools.izip
for a memory efficient solution.
使用itertools.izip
的内存有效的解决方案。
help on zip
:
帮助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.
回答by Jared
One option would be,
一种选择是,
>>> from operator import sub
>>> c = tuple(map(sub, a, b))
>>> c
(6, 6)
And itertools.imap
can serve as a replacement for map
.
并且itertools.imap
可以作为map
.
Of course you can also use other functions from operator
to add
, mul
, div
, etc.
当然,你也可以使用其他的功能operator
来add
,mul
,div
等。
But I would seriously consider moving into another data structure since I don't think this type of problem is fit for tuple
s
但我会认真考虑转向另一种数据结构,因为我认为这种类型的问题不适合tuple
s
回答by miigotu
This can also be done just as nicely without an import at all, although lambda is often undesirable:
这也可以在完全没有导入的情况下很好地完成,尽管 lambda 通常是不可取的:
tuple(map(lambda x, y: x - y, a, b))
If you are looking to get the distance between two points on say a 2d coordinate plane you should use the absolute value of the subtraction of the pairs.
如果您想获得二维坐标平面上两点之间的距离,您应该使用对减法的绝对值。
tuple(map(lambda x ,y: abs(x - y), a, b))
回答by internety
my element-wise tuple arithmetic helper
我的逐元素元组算术助手
supported operations: +, -, /, *, d
支持的操作:+、-、/、*、d
operation = 'd' calculates distance between two points on a 2D coordinate plane
operation = 'd' 计算二维坐标平面上两点之间的距离
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 ))")
回答by Kohei Kawasaki
JFYI, execution time in my laptop in 100000 times iteration
JFYI,100000 次迭代在我的笔记本电脑中的执行时间
np.subtract(a, b)
: 0.18578505516052246
np.subtract(a, b)
: 0.18578505516052246
tuple(x - y for x, y in zip(a, b))
:
0.09348797798156738
tuple(x - y for x, y in zip(a, b))
: 0.09348797798156738
tuple(map(lambda x, y: x - y, a, b))
: 0.07900381088256836
tuple(map(lambda x, y: x - y, a, b))
: 0.07900381088256836
from operator import sub tuple(map(sub, a, b))
: 0.044342041015625
from operator import sub tuple(map(sub, a, b))
: 0.044342041015625
operator looks more elegant for me.
运算符对我来说看起来更优雅。
回答by Kohei Kawasaki
As an addition to Kohei Kawasaki's answer, for speed, the original solution was actually the fastest (For a length two tuple at least).
作为对 Kohei Kawasaki 的回答的补充,对于速度,原始解决方案实际上是最快的(至少对于长度为二元组)。
>>> 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
>>>
回答by Rustam A.
Since in your question there only examples of 2-number-tuples, for such coordinate-like tuples, you may be good with simple built-in "complex" class:
由于在您的问题中只有 2-number-tuples 的例子,对于这种类似坐标的元组,您可能对简单的内置“复杂”类很好:
>>> a=complex(7,5)
>>> b=complex(1,2)
>>> a-b
>>> c=a-b
>>> c
(6+3j)
>>> c.real
6.0
>>> c.imag
3.0