SmC*_*lar 6 python arrays numpy equality list
我对python(2.7)list.remove函数感到有点困惑.在删除它的文档中说:"从列表中删除值为x的第一个项目.如果没有这样的项目,则会出错."
所以,我猜这里的价值意味着比较是基于平等(即==)而非基于身份(即is).但是,有人可以向我解释以下行为.显然,两种比较都被使用,但是以一种相当奇怪的方式:
import numpy as np
x = np.array([1,2,3])
mylist = [x, 42, 'test', x] # list containing the numpy array twice
print mylist
Run Code Online (Sandbox Code Playgroud)
当然,这将打印:
[array([1, 2, 3]), 42, 'test', array([1, 2, 3])]
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但奇怪的是,以下代码执行:
mylist.remove(x)
print mylist
Run Code Online (Sandbox Code Playgroud)
给
[42, 'test', array([1, 2, 3])]
Run Code Online (Sandbox Code Playgroud)
我希望它会抛出一个错误,因为numpy数组不返回布尔语句而是返回布尔数组.例如,x == x退货array([ True, True, True], dtype=bool).然而,我们的移除愉快地执行.但是,再次调用相同的语句会产生预测的行为:
mylist.remove(x)
Run Code Online (Sandbox Code Playgroud)
抛出一个
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-835a19b5f6a9> in <module>()
----> 1 mylist.remove(x)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?
查看源代码,list.remove使用PyObject_RichCompareBool函数来比较对象。该函数的开头包含以下内容:
/* Quick result when objects are the same.
Guarantees that identity implies equality. */
if (v == w) {
if (op == Py_EQ)
return 1;
else if (op == Py_NE)
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以它首先比较对象身份。仅当对象不同时,才会继续使用==运算符。
在您的示例中,如果x是列表中的第一个对象,它将与删除的值是同一对象,因此被上述函数视为相等并被删除。如果第一个对象是其他对象,它将x与==运算符进行比较,这将返回一个 numpy 数组并导致错误,因为它无法转换为布尔值。
该in运算符以相同的方式工作,因此x in [x,1]返回Truewhilex in [1,x]会引发错误。