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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 12:26:42  来源:igfitidea点击:

Exponentiation in Python - should I prefer ** operator instead of math.pow and math.sqrt?

pythonmathexponentiation

提问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.5is 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.sqrtis the C implementation of square root and is therefore different from using the **operator which implements Python's built-in powfunction. Thus, using math.sqrtactually gives a different answer than using the **operator and there is indeed a computational reason to prefer numpyor mathmodule 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 powfunction handles a few extra cases like "complex numbers, unbounded integer powers, and modular exponentiation".

math.sqrt是平方根的 C 实现,因此与使用**实现 Python 内置pow函数的运算符不同。因此, usingmath.sqrt实际上给出了与使用**运算符不同的答案,并且确实有一个计算原因更喜欢numpymath模块实现而不是内置。具体而言, 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 ** 2is 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.5to take the square root doesn't do the exact same computations as math.sqrtas 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.5simply because I don't want to add mathjust 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。然而,我希望平方根的特定指令比使用对数的多步运算更好(更准确)。