Python 在没有dtype参数的情况下调用np.array是否会引发错误?

Python 在没有dtype参数的情况下调用np.array是否会引发错误?,python,numpy,Python,Numpy,以下调用是否会为x的任何值引发错误: arr = np.array(x, copy=False, subok=False) 我尝试了一系列不同的输入,我认为这些输入可能无效,但我得到的最坏结果是标量数组dtype=object 我知道设置dtype参数很容易得到TypeError是的 >>> numpy.array([1, [2]], copy=False, subok=False) Traceback (most recent call last): File "<

以下调用是否会为
x
的任何值引发错误:

arr = np.array(x, copy=False, subok=False)
我尝试了一系列不同的输入,我认为这些输入可能无效,但我得到的最坏结果是标量数组
dtype=object

我知道设置
dtype
参数很容易得到
TypeError

是的

>>> numpy.array([1, [2]], copy=False, subok=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: setting an array element with a sequence.
>numpy.array([1,[2]],copy=False,subok=False)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:使用序列设置数组元素。

在NumPy版本1.14.2上进行测试,以备不时之需。

最简单的方法是向其传递一个对象,该对象的行为足够像一个序列,以获取数组,将其视为一个,但一旦开始,就将其丢弃。我记不起
array
考虑序列的确切规则,但仍然很容易找到中断的东西


例如,在意识到(通过旧式序列迭代器协议)对象的实际长度为0之前,将其混淆为构建大小为2的数组:

class BadSeq:
    def __len__(self):
        return 2
    def __getitem__(self, idx):
        raise IndexError()
现在
np.array(BadSeq())
将引发:

ValueError: cannot copy sequence with size 2 to array axis with dimension 0
相反,
list(BadSeq())
将返回一个空列表


或者完全违反顺序协议:

class BadSeq:
    def __len__(self):
        return 2
    def __getitem__(self, idx):
        raise TypeError(f"Take your {type(idx).__name__} and shove it")
现在
np.array(BadSeq())
将通过以下命令传递
TypeError

TypeError: Take your int and shove it
当然,在这里,
list
具有相同的行为


我相信您可以使用缓冲协议玩类似的把戏,但这需要构建一个C扩展,这比我想投入的工作要多。(事实上,我确实尝试过通过
ctypes.pythonapi
数组.array
中创建
内存视图,但事实证明,通过这种方式,segfault比异常更容易获得,如果这是您想要的,那么有更好的方法来实现它……)


作为旁注,以下代码不会引发异常,但可能不会执行您想要的操作:

x = []
x.append(x)
arr = np.array(x, copy=False, subok=False)
原始的
x
是一个无限维嵌套列表,但
arr
是一个32D数组,其单个元素(
arr[(1,)*32])
)作为
对象引用
x
。虽然使用有限嵌套可以有效地获得相同的结果:

y = []
for _ in range(33): y = [y[:]]
arr = np.array(y, copy=False, subok=False)

这将为您提供一个32D数组,其单个元素是一个3D嵌套列表。

它可能会引发
内存错误
@WarrenWeckesser。它还可能引发键盘中断或在该点调用的任何东西:)令人惊讶的是,
lst=[];附加(lst);arr=np。数组(lst)
不会引发异常;它提供了一个32D数组,其唯一元素是对
lst
的引用。
np.array
对支持序列API或缓冲区API的C扩展类型有什么作用,但在尝试调用它时会引发异常?@abarnert,当使用缓冲区API时,
np.ndarray
可能是一个更好的构造函数。我很惊讶它没有变成
dtype=object
。可能需要在邮件列表中询问这一点…@madpysicast Yes,特别是因为
np.array([[1],2],copy=False,subok=False)
不会引发错误。它提供了您所期望的
对象
数组。@WarrenWeckesser。作为参考,我在名单上问:@madpysicast我们注意到这种行为已经有相当一段时间了。显然,它试图基于初始条目创建一个数字数组。但是当它遇到一个嵌套更深的列表时,就会产生这个错误。我们是否希望它回溯并以
object
dtype重新开始?有些人认为
np.array
不应该生成
对象
dtype,除非您告诉它。但即便如此,制作一个等长对象或子阵列的数组也很困难。32是最大维度数。它可能在numpy源代码中的多个位置进行了硬编码。@hpaulj是的,从
y
的行为可以明显看出这一点。这个答案非常好,但当我写这个问题时,我只是想知道在特定情况下是否值得检查错误。看起来很容易导致一个值得检查的错误,很简单。我不想让你认为我对其他答案的选择在任何方面反映了我对你答案质量的看法。