为什么python有这么多相似但细微不同的功能来完成某些基本的计算任务?

为什么python有这么多相似但细微不同的功能来完成某些基本的计算任务?,python,numpy,scipy,Python,Numpy,Scipy,对不起,我太天真了,但我不太明白为什么python有这么多相似但可能细微不同的功能来完成许多基本任务 例如,python中的scipy.linspace/numpy.linspace/slice之间有什么区别? 假设我想为scipy.optimize.brute使用一个切片: scipy.optimize.brute(lambda x:-x, (slice(-100,100,3),)) 但是将slice(-100100,3)替换为numpy.linspace(-100100,3)或scipy

对不起,我太天真了,但我不太明白为什么python有这么多相似但可能细微不同的功能来完成许多基本任务

例如,python中的
scipy.linspace/numpy.linspace/slice
之间有什么区别? 假设我想为scipy.optimize.brute使用一个切片:

scipy.optimize.brute(lambda x:-x, (slice(-100,100,3),)) 
但是将
slice(-100100,3)
替换为
numpy.linspace(-100100,3)
scipy.linspace
(-100100,3)是行不通的


作为另一个例子,我不明白为什么我们有三种不同的类型
math.sin
scipy.sin
numpy.sin
等等。python设计人员提供如此多的替代方案肯定是有原因的。有什么澄清吗

关于您的具体示例,需要说明的一点是,NumPy和SciPy支持向量化(您可以将序列传递给
NumPy.sin()
,并创建一个值序列,
sin(x)
。使用
math.sin()
无法做到这一点

关于SciPy/NumPy的另一点是:

>>> import scipy as sp
>>> np.sin is sp.sin
True
它们是相同的方法!NumPy/SciPy还提供对其自己名称空间中的一些
math
module方法的访问:

>>> import math
>>> np.math.factorial is sp.math.factorial is math.factorial
True

但至于为什么没有一种通用的方法来做这些事情,我认为这正是开源软件库的集市性质:这些软件包已经成为最受欢迎和最广泛使用的软件包;没有任何自上而下的、大教堂式的计划ges输入到
暴力

scipy.optimize.brute(lambda x:-x, (slice(-100,100,3),)) 
根据其文件:

范围:元组 范围元组的每个组件必须是一个“切片对象”或一个形式(低、高)的范围元组。程序使用这些组件创建点网格,目标函数将在其上计算

numpy.linspace(-100100,3)
scipy.linspace(-100100,3)
是同一件事)。它既不是切片也不是范围元组。它或多或少是切片的扩展。但是
brute
选择对切片执行自己的操作。特别是经过某种调整后,它将其传递给
mgrid

这里没有什么神奇之处。这只是编写了
scipy.optimize
的人选择如何处理其输入


python
slice
是一个简单的对象,它具有
start
stop
step
属性,几乎没有其他属性。像
start:stop:step
这样的索引符号会被转换成片。但是像
这样的对象有责任列出
ndarray
使用这三个值。虽然
np.arange
的输入是切片式的,但
linspace
的输入不是。第三个数字是步数,而不是步长。
linspace
对端点的处理更加精细。在某些情况下,结果类似,而在其他情况下,细节很重要。

Python不“随附”numpy和scipy。如果你问为什么两个不同的第三方库有一些相似的函数,你必须问库的作者。@BrenBarn好的观点。我的意思是一般的python据我所知,在scipy和numpy中具有相同名称的大多数东西实际上都是由numpy提供的。scipy位于numpy之上,而为了方便起见,有些numpy名称空间是向scipy公开的。任何人都可以编写自己想要的库。正如Christian所说,numpy和scipy中提供的许多东西实际上是一样的。
scipy.optimize.brute(lambda x:-x, (slice(-100,100,3),))