Python 中的求幂 - 我应该更喜欢 ** 运算符而不是 math.pow 和 math.sqrt 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18965524/
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
Exponentiation in Python - should I prefer ** operator instead of math.pow and math.sqrt?
提问by heltonbiker
In my field it's very common to square some numbers, operate them together, and take the square root of the result. This is done in pythagorean theorem, and the RMS calculation, for example.
在我的领域,对一些数字进行平方,将它们一起运算,然后取结果的平方根是很常见的。例如,这是在勾股定理和 RMS 计算中完成的。
In numpy, I have done the following:
在 numpy 中,我做了以下工作:
result = numpy.sqrt(numpy.sum(numpy.pow(some_vector, 2)))
And in pure python something like this would be expected:
在纯 python 中会出现这样的情况:
result = math.sqrt(math.pow(A, 2) + math.pow(B,2)) # example with two dimensions.
However, I have been using this pure python form, since I find it much more compact, import-independent, and seemingly equivalent:
但是,我一直在使用这种纯 python 形式,因为我发现它更紧凑、独立于导入,并且看起来相当:
result = (A**2 + B**2)**0.5 # two dimensions
result = (A**2 + B**2 + C**2 + D**2)**0.5
I have heard some people argue that the **
operator is sort of a hack, and that squaring a number by exponentiating it by 0.5
is not so readable. But what I'd like to ask is if:
我听说有些人认为**
运算符有点像黑客,并且通过对数字取幂来平方一个数字0.5
不太容易阅读。但我想问的是:
"Is there any COMPUTATIONAL reason to prefer the former two alternatives over the third one(s)?"
“是否有任何计算理由更喜欢前两种选择而不是第三种?”
Thanks for reading!
谢谢阅读!
采纳答案by Shashank
math.sqrt
is the C implementation of square root and is therefore different from using the **
operator which implements Python's built-in pow
function. Thus, using math.sqrt
actually gives a different answer than using the **
operator and there is indeed a computational reason to prefer numpy
or math
module implementation over the built-in. Specifically the sqrt functions are probably implemented in the most efficient way possible whereas **
operates over a large number of bases and exponents and is probably unoptimized for the specific case of square root. On the other hand, the built-in pow
function handles a few extra cases like "complex numbers, unbounded integer powers, and modular exponentiation".
math.sqrt
是平方根的 C 实现,因此与使用**
实现 Python 内置pow
函数的运算符不同。因此, usingmath.sqrt
实际上给出了与使用**
运算符不同的答案,并且确实有一个计算原因更喜欢numpy
或math
模块实现而不是内置。具体而言, sqrt 函数可能以最有效的方式实现,而**
在大量基数和指数上运行,并且可能未针对平方根的特定情况进行优化。另一方面,内置pow
函数处理一些额外的情况,如“复数、无界整数幂和模幂”。
See this Stack Overflow question for more information on the difference between **
and math.sqrt
.
有关**
和之间区别的更多信息,请参阅此堆栈溢出问题math.sqrt
。
In terms of which is more "Pythonic", I think we need to discuss the very definition of that word. From the official Python glossary, it states that a piece of code or idea is Pythonic if it "closely follows the most common idioms of the Python language, rather than implementing code using concepts common to other languages." In every single other language I can think of, there is some math module with basic square root functions. However there are languages that lack a power operator like **
e.g. C++. So **
is probably more Pythonic, but whether or not it's objectively better depends on the use case.
至于哪个更“Pythonic”,我认为我们需要讨论这个词的定义。从官方 Python 词汇表 中,它指出,如果一段代码或想法“严格遵循 Python 语言最常见的习语,而不是使用其他语言常见的概念来实现代码”,那么它就是 Pythonic。在我能想到的每一种其他语言中,都有一些带有基本平方根函数的数学模块。但是,有些语言缺少幂运算符,**
例如 C++。所以**
可能更像 Pythonic,但客观上是否更好取决于用例。
回答by 6502
Even in base Python you can do the computation in generic form
即使在基础 Python 中,您也可以以通用形式进行计算
result = sum(x**2 for x in some_vector) ** 0.5
x ** 2
is surely not an hack and the computation performed is the same (I checked with cpython source code). I actually find it more readable (and readability counts).
x ** 2
肯定不是 hack 并且执行的计算是相同的(我检查了 cpython 源代码)。我实际上发现它更具可读性(并且可读性很重要)。
Using instead x ** 0.5
to take the square root doesn't do the exact same computations as math.sqrt
as the former (probably) is computed using logarithms and the latter (probably) using the specific numeric instruction of the math processor.
使用x ** 0.5
取平方根math.sqrt
与前者(可能)使用对数计算而后者(可能)使用数学处理器的特定数字指令进行计算时不完全相同。
I often use x ** 0.5
simply because I don't want to add math
just for that. I'd expect however a specific instruction for the square root to work better (more accurately) than a multi-step operation with logarithms.
我经常使用x ** 0.5
只是因为我不想为此添加math
。然而,我希望平方根的特定指令比使用对数的多步运算更好(更准确)。