62

在我的领域中,将一些数字平方,将它们一起运算,然后取结果的平方根是很常见的。例如,这是在勾股定理和 RMS 计算中完成的。

在numpy中,我做了以下事情:

result = numpy.sqrt(numpy.sum(numpy.pow(some_vector, 2)))

在纯 python 中会出现这样的情况:

result = math.sqrt(math.pow(A, 2) + math.pow(B,2)) # example with two dimensions.

但是,我一直在使用这种纯 python 形式,因为我发现它更紧凑、独立于导入并且看似等效:

result = (A**2 + B**2)**0.5   # two dimensions
result = (A**2 + B**2 + C**2 + D**2)**0.5

我听说有些人争辩说,**运算符有点像黑客,通过取幂来平方数字0.5不太可读。但我想问的是:

“是否有任何计算理由更喜欢前两种选择而不是第三种选择?”

谢谢阅读!

4

2 回答 2

59

math.sqrt是平方根的 C 实现,因此与使用**实现 Python 内置pow函数的运算符不同。因此,使用math.sqrt实际上给出了与使用运算符不同的答案,**并且确实有一个计算原因更喜欢numpymath模块实现而不是内置的。具体而言, sqrt 函数可能以最有效的方式实现,而**在大量基数和指数上运行,并且可能未针对平方根的特定情况进行优化。另一方面,内置pow函数处理一些额外的情况,如“复数、无界整数幂和模幂”。

**有关和之间区别的更多信息,请参阅此 Stack Overflow 问题math.sqrt

就哪个更“Pythonic”而言,我认为我们需要讨论这个词的定义。从官方 Python 词汇表中,它指出如果一段代码或想法“严格遵循 Python 语言的最常见习语,而不是使用其他语言共有的概念来实现代码”,那么它就是 Pythonic。在我能想到的每一种其他语言中,都有一些具有基本平方根函数的数学模块。但是,有些语言缺少幂运算符,**例如 C++。所以**可能更 Pythonic,但客观上是否更好取决于用例。

于 2013-09-23T18:02:54.387 回答
18

即使在基础 Python 中,您也可以以通用形式进行计算

result = sum(x**2 for x in some_vector) ** 0.5

x ** 2肯定不是 hack 并且执行的计算是相同的(我检查了 cpython 源代码)。我实际上发现它更具可读性(并且可读性很重要)。

取而代之的是取平方根不会进行与前者(可能)使用对数计算而后者(可能)使用数学处理器的特定数字指令x ** 0.5计算完全相同的计算。math.sqrt

我经常使用x ** 0.5只是因为我不想为此添加math。但是,我希望平方根的特定指令比对数的多步运算更好(更准确)。

于 2013-09-23T18:00:42.577 回答