有人可以解释为什么以下代码导致ValueError?
import heapq
import numpy as np
a = np.ones((2, 2), dtype=int)
states = []
heapq.heappush(states, (0, a))
heapq.heappush(states, (0, a.copy()))
错误消息是:
Traceback (most recent call last):
File "x.py", line 8, in <module>
heapq.heappush(states, (0, a.copy()))
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
在没有将a.copy()
添加到堆的情况下运行它可以正常工作,第二个/后续的由于某种原因是一个问题。我确实理解,[True, False, True]
数组存在一个未知真值的方面,并且无法从中确定单个True
或False
,但为什么呢? heapq
需要这样做吗?特别是只在第二种情况下?
答案 0 :(得分:4)
TL; DR:因为如果numpy数组包含多个元素,则不能将其转换为布尔值。
关于堆的一些信息:
Heaps&#34; order&#34;他们的内容(因此项目必须实现<
,但这是一个实现细节)。
然而,您可以通过为项目创建heap
来将项目插入tuple
,其中第一个元素是某个值,第二个元素是数组。
比较元组首先检查第一项是否相等,如果是,它检查第二项是否相等,等等直到它们不相等,那么它将检查它是否更小(当操作是<
)或更高(>
)。但是元组是用C实现的,而==
检查有点与Python中的不同。它使用PyObject_RichCompareBool
。特别是&#34;注意&#34;这里很重要
如果
o1
和o2
是同一个对象,则PyObject_RichCompareBool()
将始终为Py_EQ
返回1,为Py_NE
返回0。
现在让我们去numpy数组:
如果numpy.array
包含多个项目,则无法将bool
转换为>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
:
if
>>> if arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
检查隐式将条件转换为布尔值:
>>> arr > arr
array([False, False], dtype=bool)
>>> arr == arr
array([ True, True], dtype=bool)
即使比较了numpy-arrays,它们仍然是numpy数组:
==
因此,无法使用>>> if arr == arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
heapq
因此,您无法将具有多个元素的numpy数组转换为布尔值!然而现在有了一个有趣的部分:PyObject_RichCompareBool()
- 模块使用>>> arr is arr
True
>>> arr is arr.copy()
False
,因此它可以检查两个数组是否相等,但当且仅当这些数组相同时才会生效!
这就是为什么它适用于多次传递的相同数组,但是当你复制它时会失败:
{{1}}